创建表时出现MySQL错误1022

22
MySQL Workbench 使用以下 SQL 语句创建表格:
CREATE  TABLE IF NOT EXISTS `mydb`.`errors_reports` (
   `error_id` INT NOT NULL ,
   `report_short` VARCHAR(15) NOT NULL ,
PRIMARY KEY (`error_id`, `report_short`) ,
INDEX `error_id_idx` (`error_id` ASC) ,
INDEX `report_short_idx` (`report_short` ASC) ,
CONSTRAINT `error_id`
   FOREIGN KEY (`error_id` )
   REFERENCES `mydb`.`errors` (`error_id` )
   ON DELETE NO ACTION
   ON UPDATE NO ACTION,
CONSTRAINT `report_short`
   FOREIGN KEY (`report_short` )
   REFERENCES `mydb`.`reports` (`report_short` )
   ON DELETE NO ACTION
   ON UPDATE NO ACTION)
ENGINE = InnoDB

我认为这看起来不错,而且我的数据库中还有很多其他非常相似的表,MySQL创建它们也很顺利。

但是这个表格......

ERROR 1022 (23000): Can't write; duplicate key in table 'errors_reports'

我真的看不出这里有任何重复的键。只定义了一个键!
我正在运行MySQL 5.6,使用全新的默认安装。错误日志中没有任何内容。
有什么想法吗?
编辑:通过逐步排除的过程(回到表的最简单定义,然后逐渐添加位元组),问题似乎出在这一部分:
CONSTRAINT `error_id`
    FOREIGN KEY (`error_id` )
    REFERENCES `mydb`.`errors` (`error_id` )
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,

这特别奇怪,因为在几个其他表定义中有相同的代码,而那些是完全正常的!


我对这个查询没有任何问题...似乎还有其他事情发生了。 - Explosion Pills
不确定是否必须为FK列显式创建索引。我认为创建引用会自动创建索引。 - Kermit
去掉INDEX语句并不会有任何影响。 - Matt McLeod
3个回答

71
问题在于整个模型中,一个外键的名称不能与另一个外键相同。

想象这种情况:

Catalog --> Supplier

Product --> Supplier

如果表Catalog中外键的名称是“supplier”,并且您在product表中分配了相同的名称,则外键名称将会"冲突"。

您需要给它们不同的名称...

例如:

catalog_supplier product_supplier


谢谢!我也遇到了同样的问题,如果没有错误提示信息,我可能无法理解。顺便说一下,冲突的外键名称并不与列名相同,它只是一个内部 MySql 键的名称。 - uzilan
1
你知道为什么MySQL中存在那个约束吗? - vipw

2
似乎您正在对外键列创建索引。在InnoDb中创建外键时,将自动创建一个索引。请参见此主题

该代码是由MySQL Workbench生成的,它似乎明确添加了这一点。虽然这并没有什么区别。 - Matt McLeod
@MattMcLeod 你能在表格创建后创建约束吗?在表格创建前/后,你也可以尝试检查索引 - Kermit
1
啊哈!这让我相信我找到了解决方案:另一个表已经应用了相同的约束条件,即error_id,并且Workbench给这两个表分配了相同的约束名。更改约束名称允许创建它。 - Matt McLeod
@MattMcLeod 很高兴听到你找到了问题的根源。让MySQL生成约束名会更容易些。 - Kermit

-2

尝试使用INSERT IGNORE代替INSERT,如果发现重复的主键,则不会插入新行。这应该可以暂时解决问题,但我建议截断表。


这是创建表,而不是插入数据。这里没有进行插入操作。 - Matt McLeod
没错,这绝对是外键问题(对我来说是错误105)。确保外键和引用列具有相同的数据类型,例如排序规则、默认属性等。 - jacek_podwysocki

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