MySQL 1062-дубликат записи ' 0 'для ключа 'PRIMARY'
у меня есть следующая таблица в MySQL версии 5.5.24
DROP TABLE IF EXISTS `momento_distribution`;
CREATE TABLE IF NOT EXISTS `momento_distribution`
(
`momento_id` INT(11) NOT NULL,
`momento_idmember` INT(11) NOT NULL,
`created_at` DATETIME DEFAULT NULL,
`updated_at` DATETIME DEFAULT NULL,
`unread` TINYINT(1) DEFAULT '1',
`accepted` VARCHAR(10) NOT NULL DEFAULT 'pending',
`ext_member` VARCHAR(255) DEFAULT NULL,
PRIMARY KEY (`momento_id`, `momento_idmember`),
KEY `momento_distribution_FI_2` (`momento_idmember`),
KEY `accepted` (`accepted`, `ext_member`)
)
ENGINE=InnoDB
DEFAULT CHARSET=latin1;
Он имеет много данных с отношениями "многие к одному" с двумя другими таблицами с ondelete=restrict
и onupdate=restrict
.
теперь мне нужно изменить структуру и ввести отдельный первичный ключ в таблицу, сохраняя при этом существующие отношения и данные. Для этого я выполнил следующий запрос:
ALTER TABLE `momento_distribution` ADD `id` INT( 11 ) NOT NULL FIRST;
ALTER TABLE `momento_distribution` DROP PRIMARY KEY , ADD PRIMARY KEY ( `id` );
к сожалению, мой второй запрос не удался со следующей ошибкой:
1062-дубликат записи " 0 "для ключа "PRIMARY"
кто-нибудь может указать на проблему? Я предполагаю, что проблема заключается в существующем отношении, но я не хочу терять существующее отношение или данные, которые имеют несколько тысяч строк. Есть ли способ сделать это без потери данных?
EDIT: Просматривая данные, я получил, что вновь созданный столбец имеет значение " 0 " в нем. Вероятно, это не позволяет изменить первичный ключ из-за дублирования записи (в новом первичном ключе)
у меня более 8000 строк, поэтому я не могу изменить его вручную. Есть ли способ назначить rowid
к новому первичному ключу?
4 ответов
выполните следующий запрос в консоли MySQL:
SHOW CREATE TABLE momento_distribution
проверить строку, которая выглядит как
CONSTRAINT `momento_distribution_FK_1` FOREIGN KEY (`momento_id`) REFERENCES `momento` (`id`)
это может быть по-другому, я просто догадываюсь, что это может быть. Если у вас есть внешний ключ на обоих "momento_id" & "momento_idmember", вы получите два имени внешнего ключа. Следующий шаг-удаление внешних ключей. Выполните следующие запросы:
ALTER TABLE momento_distribution DROP FOREIGN KEY momento_distribution_FK_1
ALTER TABLE momento_distribution DROP FOREIGN KEY momento_distribution_FK_2
обязательно измените имя внешнего ключа на то, что у вас есть от CREATE TABLE
запрос. Теперь у вас нет внешних ключей, поэтому вы можете легко удалить первичный ключ. Попробуйте следующее:
ALTER TABLE `momento_distribution` DROP PRIMARY KEY
добавить требуемый столбец следующим образом:
ALTER TABLE `momento_distribution` ADD `id` INT( 11 ) NOT NULL PRIMARY KEY AUTO_INCREMENT FIRST
этот запрос также добавляет числа, поэтому вам не нужно будет зависеть от @rowid. Теперь нужно добавить внешний ключ обратно в предыдущих статьях. Для этого сначала сделайте следующие индексы:
ALTER TABLE `momento_distribution` ADD INDEX ( `momento_id` )
ALTER TABLE `momento_distribution` ADD INDEX ( `momento_idmember` )
теперь добавьте внешние ключи. Измените ссылочную таблицу / столбец, как вы нужно:
ALTER TABLE `momento_distribution` ADD FOREIGN KEY ( `momento_id`) REFERENCES `momento` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT
ALTER TABLE `momento_distribution` ADD FOREIGN KEY ( `momento_idmember`) REFERENCES `member` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT
надеюсь, что это поможет. Если вы получаете какие-либо ошибки, отредактируйте вопрос со структурой ссылочных таблиц и кодом(кодами) ошибки, который вы получаете.
вам нужно указать первичный ключ как auto-increment
CREATE TABLE `momento_distribution`
(
`momento_id` INT(11) NOT NULL AUTO_INCREMENT,
`momento_idmember` INT(11) NOT NULL,
`created_at` DATETIME DEFAULT NULL,
`updated_at` DATETIME DEFAULT NULL,
`unread` TINYINT(1) DEFAULT '1',
`accepted` VARCHAR(10) NOT NULL DEFAULT 'pending',
`ext_member` VARCHAR(255) DEFAULT NULL,
PRIMARY KEY (`momento_id`, `momento_idmember`),
KEY `momento_distribution_FI_2` (`momento_idmember`),
KEY `accepted` (`accepted`, `ext_member`)
)
ENGINE=InnoDB
DEFAULT CHARSET=latin1$$
что касается комментариев ниже, как насчет:
ALTER TABLE `momento_distribution`
CHANGE COLUMN `id` `id` INT(11) NOT NULL AUTO_INCREMENT,
DROP PRIMARY KEY,
ADD PRIMARY KEY (`id`);
первичный ключ-это уникальный индекс, поэтому, если он содержит дубликаты, вы не можете назначить столбец уникальным индексом, поэтому вам может потребоваться создать новый столбец в целом
этот шаг отлично работает для меня.. вы можете попробовать
- добавить индексации
- Добавить Автоувеличение
- Добавить Первичный Ключ
надеюсь, это сработает и для вас. удачи!--1-->