错误1022-无法写入;表中的重复键


218

关于create table命令上的重复键,我收到1022错误。看完查询后,我不知道重复发生在哪里。有人可以看到吗?

SQL query:

-- -----------------------------------------------------
-- Table `apptwo`.`usercircle`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS  `apptwo`.`usercircle` (

 `idUserCircle` MEDIUMINT NOT NULL ,
 `userId` MEDIUMINT NULL ,
 `circleId` MEDIUMINT NULL ,
 `authUser` BINARY NULL ,
 `authOwner` BINARY NULL ,
 `startDate` DATETIME NULL ,
 `endDate` DATETIME NULL ,
PRIMARY KEY (  `idUserCircle` ) ,
INDEX  `iduser_idx` (  `userId` ASC ) ,
INDEX  `idcategory_idx` (  `circleId` ASC ) ,
CONSTRAINT  `iduser` FOREIGN KEY (  `userId` ) REFERENCES  `apptwo`.`user` (
`idUser`
) ON DELETE NO ACTION ON UPDATE NO ACTION ,
CONSTRAINT  `idcategory` FOREIGN KEY (  `circleId` ) REFERENCES  `apptwo`.`circle` (
`idCircle`
) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE = INNODB;

MySQL said: Documentation

#1022 - Can't write; duplicate key in table 'usercircle' 

4
如果我没记错的话,主键始终也是UNIQUE INDEX,那么您将不得不删除唯一索引语句吗?
2013年

1
ON DELETE NO ACTION只会丢弃外键的全部使用。除非您有非常特殊的原因要这样做。
AmazingDreams 2013年

4
@AmazingDreams为什么?它仍然强制执行参照完整性。只有您必须自己删除孩子。这比级联删除更安全,在级联删除中,您可以通过删除一个不正确的关键字来意外删除大量数据。
GolezTrol

1
stackoverflow.com/a/5810024/1567737为什么在使用“别名”时使用别名可以立即使目的明确?
AmazingDreams

@AmazingDreams感谢您的提示。我也喜欢围绕它的辩论-它有助于我了解优缺点。
2013年

Answers:


534

您很可能已经在名称iduseridcategory数据库中具有约束。如果是这样,只需重命名约束即可。

约束对于整个数据库必须是唯一的,而不仅仅是对要创建/更改的特定表。

要找出约束当前在哪里使用,可以使用以下查询:

SELECT `TABLE_SCHEMA`, `TABLE_NAME`
FROM `information_schema`.`KEY_COLUMN_USAGE`
WHERE `CONSTRAINT_NAME` IN ('iduser', 'idcategory');

15
就像你说的那样。在其余的CREATE查询中,使用相同的idcategory iduser名称自动生成了许多约束-感谢您的帮助!
2013年

1
我以为MySQL Workbench在导出创建脚本时会解决此问题,但这就是我在打开项目时“忽略”此类警告的原因。
SnowInferno 2014年

谢谢你,队友:)这对我有很大帮助,现在我的外键约定有所不同,我再也遇到了这个问题:)

可以确认一下。但是,尽管已删除引用表,但如果存在命名约束,该怎么办?我可以从不存在的表中删除约束吗?我想我应该从MySQL 5.6更新到当前的MariaDB。
Anse

3
谢谢您:约束对于整个数据库必须是唯一的
sebasira

31

在MySQL中更改外键名称。数据库表中不能具有相同的外键名称。

检查所有表和所有外键,并避免两个外键具有相同的确切名称。


就我而言,这就是问题所在。我永远都不会猜到,您就挽救了我的一天。现在使用fk_id_1,fk_id_2等。谢谢。
JackLeEmmerdeur

15

成功解决的两个链接和命名约定这两个方面,我轻松地解决了我所遇到的相同问题。即,对于外键名称,给定为fk _colName_ TableName。此命名约定是明确的,并且还使数据库模型中的每个ForeignKey都是唯一的,并且您将永远不会收到此错误。

错误1022:无法写入;表中的重复键


6

正如其他人提到的那样,您的约束名称可能已被DB中的另一个表使用。它们在整个数据库中必须是唯一的。

命名外键约束的一个好习惯是:

fk_TableName_ColumnName

要调查是否存在冲突,可以通过此查询列出数据库使用的所有约束:

SELECT * FROM information_schema.table_constraints WHERE constraint_schema = 'YOUR_DB';

当我运行该查询时,我发现我以前已经制作了一个表的临时副本,并且该副本已经使用了我尝试使用的约束名称。


4

最近4个小时,我都遇到了同样的问题。我所做的只是确保约束具有唯一的名称。

您可以重命名约束。我在我的后面附加了一个数字,以便可以轻松跟踪出现的次数。

如果表中的约束名为带有外键X的boy,则下一个具有外键X的约束可以称为boy1

我相信您会找到比我更好的名字。🙂


3

这也可能与Percona Toolkit的在线模式更改工具某些版本中的错误有关。要变异一个大表,pt-osc首先创建一个重复表并将所有记录复制到该表中。在某些情况下,某些版本的pt-osc 2.2.x会尝试赋予新表约束与旧表约束相同的名称。

修复程序在2.3.0中发布。

有关更多详细信息,请参见https://bugs.launchpad.net/percona-toolkit/+bug/1498128


1

我也遇到了这个问题。检查数据库名称是否已经存在于Mysql中,并重命名旧数据库。


1

创建新表时遇到了这个问题。原来,我给的外键名称已经被使用。重命名该键可以修复它。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.