【问题标题】:Adding Foreign Key Fails in MySQL - errno 150 - using mysqldump在 MySQL 中添加外键失败 - errno 150 - 使用 mysqldump
【发布时间】:2013-10-23 21:06:34
【问题描述】:

更新:该死 - 你不知道我发布的那一刻我得到了啊哈!主表需要在创建中排在第一位。

更新 2:对于以下任何人,问题出在我的包含 --compact 选项的 mysqldump 命令上。这删除了包括 FOREIGN_KEY_CHECKS=0; 的 mysqldump 功能。在转储文件的顶部。现在去掉compact,问题就彻底解决了。无需手动将其插入到我的转储文件中。

做mysqldump的时候可以指定表的顺序吗?

我正在将 localhost MySQL 数据库上传到我的共享服务器。尝试使用外键重新创建表时出现以下错误。 “#1005 - 无法创建表 'username_test.gemdetail' (errno: 150)” sql 语句如下。去掉约束子句后,表导入就好了)

来自 MySQL - FOREIGN KEY Constraints 文档: 如果您重新创建已删除的表,则它必须具有符合引用它的外键约束的定义。如前所述,它必须具有正确的列名和类型,并且必须在引用的键上具有索引。如果不满足这些,MySQL 将返回错误号 1005 并在错误消息中引用错误 150。

我检查了以下情况(如果我遗漏了什么,请纠正我):

1) 这两个表必须是 ENGINE=InnoDB。 - 是的 2) 这两个表必须具有相同的字符集。 - 是的 3)父表中的PK列和FK列必须是相同的数据类型。 - 是的 4)父表中的PK列和FK列,如果有定义的排序规则类型,则必须具有相同的排序规则类型; - 没有定义的 5)如果外键表中已有数据,则外键列值必须与父表PK列中的值匹配。 - 没有数据 6) 并且子表不能是临时表。 - 不适用

我也尝试过导入新的空数据库。有任何想法吗?提前感谢您的帮助。

mysqldump 生成的 sql 代码的相关部分(为了便于阅读,我删除了其他列和键,但这个精简的代码产生了相同的结果):

DROP TABLE IF EXISTS `gemdetail`;
CREATE TABLE `gemdetail` (
  `gemdetailid` int(10) NOT NULL AUTO_INCREMENT,
  `gemid` int(10) NOT NULL,
  PRIMARY KEY (`gemdetailid`),
  KEY `gemid` (`gemid`),
  CONSTRAINT `gemdetail_ibfk_1` FOREIGN KEY (`gemid`) REFERENCES `gems` (`gemid`) ON DELETE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=875 DEFAULT CHARSET=utf8;

DROP TABLE IF EXISTS `gems`;
CREATE TABLE `gems` (
  `gemid` int(10) NOT NULL AUTO_INCREMENT,
  `userid` int(10) NOT NULL,
  PRIMARY KEY (`gemid`),
  KEY `userid` (`userid`)
) ENGINE=InnoDB AUTO_INCREMENT=528 DEFAULT CHARSET=utf8;

最后是数据库版本信息:

服务器:通过 UNIX 套接字的本地主机 软件:MySQL 软件版本:5.5.32-log - MySQL Community Server (GPL) (BetterLinux 01 Sep 5 2013 23:04:40) 协议版本:10

【问题讨论】:

  • 是的,有时我们并不总是知道真正的问题是什么。至于不清楚,@Filipe Silva 能够在不产生全新问题的情况下给出答案。与其他帖子一样,任何搜索此问题的人通常都会将这些问题结合在一起。

标签: mysql foreign-keys


【解决方案1】:

你必须先创建表 gems,因为你在 gemdetail 表中引用它,所以它必须存在:

DROP TABLE IF EXISTS `gems`;
CREATE TABLE `gems` (
  `gemid` int(10) NOT NULL AUTO_INCREMENT,
  `userid` int(10) NOT NULL,
  PRIMARY KEY (`gemid`),
  KEY `userid` (`userid`)
) ENGINE=InnoDB AUTO_INCREMENT=528 DEFAULT CHARSET=utf8;

DROP TABLE IF EXISTS `gemdetail`;
CREATE TABLE `gemdetail` (
  `gemdetailid` int(10) NOT NULL AUTO_INCREMENT,
  `gemid` int(10) NOT NULL,
  PRIMARY KEY (`gemdetailid`),
  KEY `gemid` (`gemid`),
  CONSTRAINT `gemdetail_ibfk_1` FOREIGN KEY (`gemid`) REFERENCES `gems` (`gemid`) ON DELETE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=875 DEFAULT CHARSET=utf8;

sqlfiddle demo

要在 mysqldump 之后创建表并且不给出外键错误,请打开转储文件,将以下语句放在开头:

SET FOREIGN_KEY_CHECKS=0; 

【讨论】:

  • 是的,这是最终的解决方案,也是解决问题的方法。谢谢。
  • 我只想竖起大拇指(他落后你几秒钟)。我已经纠正了。再次感谢。
  • 我能够解决这个问题,而无需每次都编辑转储文件。我从 mysqldump 命令中删除了 --compact 选项。
【解决方案2】:

你应该在“gemdetail”之前创建“gem”,切换创建查询。

【讨论】:

  • 我明白了!在我发布后回答第二个。感谢您快速回复。现在的问题是我可以使用 mysqldump 正确放置表的顺序吗?目前我使用:mysqldump -h localhost -u user -ppassword --compact --add-drop-table --quick dbname >dump.sql
  • 对不起,我还没有听说过诸如此类的事情...我搜索了一下,但没有任何内容...禁用 foreign_key_checks 只会使您的插入查询更快,而不是忽略制造问题
  • 更快的插入以任何顺序创建表的能力:dev.mysql.com/doc/refman/5.6/en/create-table-foreign-keys.html ...在不匹配(例如针对列不同的数据类型)仍然会引发错误。
  • 是的,你是对的,我错了。我学到了更多:) 谢谢你的信息。
猜你喜欢
  • 1970-01-01
  • 2012-10-17
  • 1970-01-01
  • 1970-01-01
  • 2015-06-20
  • 2011-09-02
  • 2012-01-01
  • 2013-05-12
  • 2011-05-03
相关资源
最近更新 更多