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`);

первичный ключ-это уникальный индекс, поэтому, если он содержит дубликаты, вы не можете назначить столбец уникальным индексом, поэтому вам может потребоваться создать новый столбец в целом


проверьте, установлено ли в поле с первичным ключом значение auto increment


этот шаг отлично работает для меня.. вы можете попробовать

  1. добавить индексации
  2. Добавить Автоувеличение
  3. Добавить Первичный Ключ

надеюсь, это сработает и для вас. удачи!--1-->