Подтвердить что ты не робот

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 новому Первичному ключу?

4b9b3361

Ответ 1

Выполните следующий запрос в консоли 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 

Надеюсь, это поможет. Если вы получили какие-либо ошибки, пожалуйста, отредактируйте вопрос со структурой справочных таблиц & код ошибок, которые вы получаете.

Ответ 2

Вам нужно указать первичный ключ как автоматическое приращение

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

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

Ответ 3

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

Ответ 4

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

  • Добавить индексирование
  • Добавить автоинкремент
  • Добавить первичный ключ

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

Ответ 5

Установите свой ПЕРВИЧНЫЙ КЛЮЧ как AUTO_INCREMENT.

Ответ 6

Для меня я забыл добавить AUTO_INCREMENT в мое основное поле и вставил данные без идентификатора.

Ответ 7

Установите AUTO_INCREMENT на ПЕРВИЧНЫЙ КЛЮЧ