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
новому Первичному ключу?
Ответы
Ответ 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 на ПЕРВИЧНЫЙ КЛЮЧ