【发布时间】:2016-05-15 10:54:19
【问题描述】:
我已经使用 mysqldumnp(从 MySQL 5.6.27)创建了一个 SQL 文件,并正在使用它来重新创建一个数据库(到 MySQL 5.7.9):
CREATE TABLE `my_table` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`email` varchar(255) DEFAULT NULL,
`user_id` bigint(20) unsigned DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `user_id` (`user_id`),
CONSTRAINT `my_table_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;
我收到此错误:
[Err] 1215 - 无法添加外键约束
然后我运行查询SHOW ENGINE INNODB STATUS 并得到以下形式的“最新外键错误”标题:
2016-02-05 12:27:08 0x7f1b8f54b700 外键约束错误 表 my_db/my_table:外键 (
user_id) 参考users(user_id) ENGINE=InnoDB 默认字符集=utf8 ROW_FORMAT=COMPACT: 无法解析接近的表名:(user_id)) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT
在运行set FOREIGN_KEY_CHECKS = 0; 后,我也尝试运行此 SQL 命令,但仍然出现相同的错误。
这似乎表明问题在于users 表必须在我可以运行此查询之前就位。但是,我有另一部分 SQL 转储(在此部分之前)具有引用完全相同的表和列的外键约束 - users.user_id - 并且运行没有任何错误。
原来如此, 1) 对为什么会发生这种情况感到困惑,并且 2)想知道是否有任何方法可以指示mysqldump格式化转储文件,使创建表的命令首先出现在转储文件中,然后添加外键的命令出现,从而规避问题使用不存在的表。
注意:我还使用 Navicat 中的数据传输工具在转储文件包含的同一个数据库中进行复制,并且运行正常。这似乎表明无论 Navicat 例程如何处理约束,但尝试使用命令行导入转储文件却没有。
【问题讨论】:
-
请显示您的表格
users -
运行 CREATE TABLE
my_table... 命令时,表 'users' 不存在,那么您为什么要看到这个? -
你为这个表创建了一个外键,所以它必须存在
-
如前所述,转储文件中有一个查询,该查询还参考 users.user_id(默认为 NULL)创建了一个外键,并且运行成功,所以不能这样.如果是这种情况,为什么 mysqldump 不将所有外键创建添加到转储文件的末尾以避免重新创建数据库时所有表都不会到位的问题,直到整个文件内容被执行。