MySQL 创建表时出现错误 1022
Posted
技术标签:
【中文标题】MySQL 创建表时出现错误 1022【英文标题】:MySQL error 1022 when creating table 【发布时间】:2013-02-07 12:07:07 【问题描述】: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,
这特别奇怪,因为在其他几个表定义中有相同的代码,而且完全没问题!
【问题讨论】:
我对这个查询没有任何问题.. 好像还有其他事情发生 不确定是否必须为 FK 列显式创建索引。我的印象是创建引用会创建一个索引。 取出 INDEX 语句没有任何区别。 【参考方案1】:问题是外键的名称不能与另一个外键相同在整个模型中。
想象一下这种情况
目录 --> 供应商
产品 --> 供应商
如果供应商表 Catalog 中的外键名称是“供应商”,并且您在产品表中分配了相同的名称,则外键名称将“冲突”。
你需要给它们起不同的名字..
例如:
目录供应商 产品供应商
【讨论】:
谢谢!有同样的问题,鉴于错误按摩无法理解。顺便说一句,冲突外键的名称与列名不同,只是键的内部 MySql 名称。 你知道 MySQL 中为什么存在这个约束吗?【参考方案2】:您似乎正在为外键列创建索引。在 InnoDb 中创建外键时,会自动创建一个。
See this thread.
【讨论】:
代码是由 MySQL Workbench 生成的,它似乎明确地添加了这一点。并不是说它有什么不同。 @MattMcLeod 你能在创建表后创建约束吗?您也可以在创建表之前/之后尝试checking the indexes 吗? 啊哈!这使我想到了我认为的解决方案:另一个表已经应用了相同的约束 re:error_id,并且 Workbench 给了这两个相同的约束名称。更改约束名称允许创建它。 @MattMcLeod 很高兴听到您找到了问题的根源。让 MySQL 生成约束名更容易。【参考方案3】:尝试使用INSERT IGNORE
而不是INSERT
,如果发现重复的主键,INSERT IGNORE 将不会插入新行。这应该有助于暂时解决问题,但我建议截断表格。
【讨论】:
这是创建表,而不是插入数据。这里没有 INSERT。 对。这绝对是外键问题(对我来说是错误 105)。确保外键和引用列具有相同的数据类型,例如排序规则、默认属性等。以上是关于MySQL 创建表时出现错误 1022的主要内容,如果未能解决你的问题,请参考以下文章