MySQL 1062 - 主键 'PRIMARY' 重复输入值 '0'

53

我在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=restrictonupdate=restrict

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

ALTER TABLE  `momento_distribution` ADD  `id` INT( 11 ) NOT NULL FIRST;
ALTER TABLE  `momento_distribution` DROP PRIMARY KEY , ADD PRIMARY KEY (  `id` );

很遗憾,我的第二个查询失败了,出现了以下错误:

1062 - 主键“PRIMARY”重复输入'0'

有人能指出问题吗?我想问题可能出在现有的关系上,但我不想失去已有的关系或数据,这些数据有几千行。有没有办法在不丢失数据的情况下解决这个问题?

编辑: 通过查看数据,我发现新创建的列中有值“0”。可能由于新的主键中存在重复记录,这样就不能更改主键。

我有超过8,000行数据,所以无法手动更改。有没有办法将rowid分配给新的主键?


1
你的编辑说明默认值为0对我很有帮助。看起来在我的情况下,我的表在添加自动递增之前就被创建了(没有ID,默认为0)。 - Wouter Vanherck
我曾经遇到过同样的错误。在我的情况下,问题是我正在管理一个非空表格。我通过执行TRUNCATE TABLE name_table来解决问题,然后我就能够添加主键了。 - franz1
9个回答

68

您需要将主键设置为自增长。

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

主键是一个唯一索引,如果它包含重复值,你就不能将该列分配为唯一索引,因此你可能需要创建一个全新的列。


谢谢Merca,但是我只是把上面的查询作为表结构的参考。我不是在创建新表。我已经有了一张有很多行的表,所以只能使用alter查询。目前momento_id和momento_idmember是外键和复合键。我需要将它们移除作为主键,并引入一个新列作为主键。 - Kapil Sharma
抱歉,编辑也行不通。momento_id已经是主键之一,与momento_idmember一起。我需要一个新的列作为主键。请检查我的帖子,我已经成功使用查询“ **ALTER TABLE 'momento_distribution' ADD 'id' INT(11) NOT NULL FIRST;**”添加了列。现在需要将其设置为主键。 - Kapil Sharma
主键是一个唯一索引,因此如果它包含重复项,则无法将该列分配为唯一索引,因此您可能需要创建一个全新的列。 - Miroslav
是的,这就是原因。请检查问题末尾的编辑。MySQL 中有 @rowid。试图将其分配为值。这是否可能? - Kapil Sharma
我在PHPMyAdmin中导出了表结构,但是在导入时主键上的自增选项不知何故被忽略了。 - Peter Chaula
显示剩余2条评论

25
在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 

希望这能有所帮助。如果出现任何错误,请编辑问题并提供参考表的结构和您遇到的错误代码。

谢谢@Youthpark,我正在尝试这些查询,并在接下来的10分钟内回复。感谢你的帮助。我对那个问题真的很沮丧。 - Kapil Sharma
1
如遇任何问题,请提供所有表格的结构和错误代码。 - user1586443
1
终于完成了。我从昨天开始就卡住了。非常感谢。 - Kapil Sharma

14

检查您的主键字段是否设置为自动递增


9

我经过尝试后,觉得这个步骤非常有效。你也可以试试看。

  1. 添加索引
  2. 添加自增字段
  3. 添加主键

希望对你有所帮助。祝好运!


2
这种方法的步骤或流程会很有帮助。 - Michael G

6

将你的PRIMARY KEY设置为AUTO_INCREMENT。


1

对于我来说,我忘记在我的主键字段上添加AUTO_INCREMENT并插入了没有ID的数据。


0

AUTO_INCREMENT设置为PRIMARY KEY


0
我遇到了这个错误, 使用了typeorm迁移Api,如上所述的错误是由于id没有自动递增造成的, 因此,如果您正在使用typeorm的Api迁移来编写迁移, 当您编写id列时,请使用以下内容设置id列。 { name: "id", type: "int auto_increment", isPrimary: true }

-1

删除表并重新创建。这对我有用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接