MySQL 1062 - 密钥'PRIMARY'的重复条目'0'

Kap*_*rma 38 mysql sql mysql5

我在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;
Run Code Online (Sandbox Code Playgroud)

它有大量的数据与两个其他表多到一个关系ondelete=restrictonupdate=restrict.

现在,我需要更改结构并在表中引入单独的主键,同时仍保留现有的关系和数据.为此,我执行了以下查询:

ALTER TABLE  `momento_distribution` ADD  `id` INT( 11 ) NOT NULL FIRST;
ALTER TABLE  `momento_distribution` DROP PRIMARY KEY , ADD PRIMARY KEY (  `id` );
Run Code Online (Sandbox Code Playgroud)

不幸的是,我的第二个查询失败,出现以下错误:

1062 - 键'PRIMARY'重复输入'0'

有人可以指出这个问题吗?我想问题是现有的关系,但我不想丢失现有的关系或数据,它有几千行.有没有办法在不丢失数据的情况下做到这一点?

编辑: 通过查看数据,我得到新创建的列的值为"0".可能由于重复记录(在新的主键中)不允许更改主键

我有超过8,000行,所以我不能手动更改它.有没有办法分配rowid给新的主键?

Mir*_*lav 56

您需要将主键指定为自动增量

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$$
Run Code Online (Sandbox Code Playgroud)

关于以下评论,如何:

ALTER TABLE `momento_distribution`
  CHANGE COLUMN `id` `id` INT(11) NOT NULL AUTO_INCREMENT,
  DROP PRIMARY KEY,
  ADD PRIMARY KEY (`id`);
Run Code Online (Sandbox Code Playgroud)

PRIMARY KEY是一个唯一索引,因此如果它包含重复项,则不能将该列指定为唯一索引,因此您可能需要完全创建一个新列


小智 19

在mysql控制台中运行以下查询:

SHOW CREATE TABLE momento_distribution
Run Code Online (Sandbox Code Playgroud)

检查看起来像的线

CONSTRAINT `momento_distribution_FK_1` FOREIGN KEY (`momento_id`) REFERENCES `momento` (`id`)
Run Code Online (Sandbox Code Playgroud)

它可能有所不同,我只是猜测它可能是什么.如果'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
Run Code Online (Sandbox Code Playgroud)

请务必将外键名称更改为从CREATE TABLE查询中获得的名称.现在您没有任何外键,因此您可以轻松删除主键.请尝试以下方法:

ALTER TABLE  `momento_distribution` DROP PRIMARY KEY
Run Code Online (Sandbox Code Playgroud)

添加所需的列,如下所示:

ALTER TABLE  `momento_distribution` ADD  `id` INT( 11 ) NOT NULL  PRIMARY KEY AUTO_INCREMENT FIRST
Run Code Online (Sandbox Code Playgroud)

此查询还会添加数字,因此您无需依赖@rowid.现在,您需要将外键添加回较早的列.为此,首先制作以下索引:

ALTER TABLE  `momento_distribution` ADD INDEX (  `momento_id` )
ALTER TABLE  `momento_distribution` ADD INDEX (  `momento_idmember` )
Run Code Online (Sandbox Code Playgroud)

现在添加外键.根据需要更改参考表/列:

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 
Run Code Online (Sandbox Code Playgroud)

希望有所帮助.如果您遇到任何错误,请使用参考表的结构和您获得的错误代码编辑问题.


小智 12

检查具有主键的字段是否设置为自动增量


小智 7

这一步对我来说很完美..你可以尝试一下

  1. 添加索引
  2. 添加自动增量
  3. 添加主键

希望它也适合你.祝好运

  • 此方法的步骤或过程会有所帮助。 (2认同)

小智 6

将您的 PRIMARY KEY 设置为 AUTO_INCREMENT。