【问题标题】:MySQL: Duplicate Key Error 1022 for non duplicate keyMySQL:非重复键的重复键错误 1022
【发布时间】:2020-08-27 14:07:36
【问题描述】:

我正在尝试创建一个具有不同外键约束的表,但 mysql 抱怨此 DDL:

CREATE TABLE tasks (
        id INTEGER NOT NULL AUTO_INCREMENT, 
        `createdAt` DATETIME NOT NULL DEFAULT now(), 
        `updatedAt` DATETIME NOT NULL DEFAULT NOW() ON UPDATE NOW(), 
        `createdBy_user_id` INTEGER NOT NULL, 
        `updatedBy_user_id` INTEGER NOT NULL, 
        status ENUM('open','closed') NOT NULL, 
        customer_id INTEGER NOT NULL, 
        `projectDescription` TEXT, 
        PRIMARY KEY (id), 
        CONSTRAINT user_id_fk FOREIGN KEY(`createdBy_user_id`) REFERENCES users (id), 
        CONSTRAINT customer_id_fk FOREIGN KEY(customer_id) REFERENCES `Customer` (id), 
        CONSTRAINT user_up_id_fk FOREIGN KEY(`updatedBy_user_id`) REFERENCES users (id)
)COLLATE utf8mb4_german2_ci CHARSET=utf8mb4

我收到错误 ERROR 1022 (23000): Can't write; duplicate key in table 'tasks',这毫无意义,因为每个约束都有不同的名称并应用于不同的列。

奇怪的是,如果我删除 fk-suffix 并将其替换为 constr 之类的东西,MySQL 不会抱怨。

有人知道为什么 MySQL 5.7 (Server version: 5.7.30-33 Percona Server (GPL), Release 33, Revision 6517692) 会这样吗?

【问题讨论】:

  • 我不能reproduce this problem。您确定这是您的确切代码吗?
  • 是的。它由数据库迁移工具生成并产生此错误。也许我应该提到我使用Server version: 5.7.30-33 Percona Server (GPL), Release 33, Revision 6517692

标签: mysql foreign-keys constraints percona


【解决方案1】:

您在另一个表中使用了同名约束。

这是一种轻松重现此问题的方法:

CREATE TABLE foo
(
  id int not null auto_increment primary key
);

CREATE TABLE bar
(
  id int not null auto_increment primary key,
  foo_id int,
  
  CONSTRAINT foo_id_fk FOREIGN KEY(`foo_id`) REFERENCES foo(id) -- <- Check this constraint name
);

CREATE TABLE hello
(
  id int not null auto_increment primary key,
  foo_id int,
  
  CONSTRAINT foo_id_fk FOREIGN KEY(`foo_id`) REFERENCES foo(id) -- <-- same constraint name than before
);

架构错误:错误:ER_DUP_KEY:无法写入;表 'hello' 中的重复键

要解决此问题,请确保 FK 名称是唯一的。您可以省略约束的命名,因此 MySQL 会为您创建一个。

--        v----------- no name here
CONSTRAINT FOREIGN KEY(`createdBy_user_id`) REFERENCES users (id)

或者您可以使用naming convention

【讨论】:

  • 谢谢,来自服务器的错误信息真的很误导,因为它让你认为问题是同一个表中的两个相等的键。
猜你喜欢
  • 1970-01-01
  • 2013-08-06
  • 1970-01-01
  • 2017-01-31
  • 2019-09-08
  • 1970-01-01
  • 2014-07-01
  • 1970-01-01
相关资源
最近更新 更多