MySQL:不能创build表(errno:150)

我正在尝试导入.sql文件,并在创build表时失败。

这是查询失败:

CREATE TABLE `data` ( `id` int(10) unsigned NOT NULL, `name` varchar(100) NOT NULL, `value` varchar(15) NOT NULL, UNIQUE KEY `id` (`id`,`name`), CONSTRAINT `data_ibfk_1` FOREIGN KEY (`id`) REFERENCES `keywords` (`id`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=latin1; 

我从同一个数据库中导出.sql,我删除了所有的表,现在我试图导入它,为什么它失败?

MySQL:不能创build表'./dbname/data.frm'(errno:150)

从MySQL – FOREIGN KEY约束文档 :

如果您重新创build一个被删除的表,它必须有一个符合引用它的外键约束的定义。 它必须具有正确的列名称和types,并且必须在引用键上具有索引,如前所述。 如果这些不满足,MySQL将返回错误1005并引用错误消息中的错误150,这意味着外键约束未正确形成。 同样,如果由于错误150而导致ALTER TABLE失败,这意味着对于已更改的表,外键定义将不正确地形成。

错误150意味着你的外键有问题。 外来的钥匙可能不是完全一样的?

您可以通过运行SHOW ENGINE INNODB STATUS;来获得实际的错误信息SHOW ENGINE INNODB STATUS; 然后在输出中寻找LATEST FOREIGN KEY ERROR

来源: 另一位用户在类似问题中的回答

数据types必须完全匹配。 如果您正在处理varchartypes,则表必须使用相同的sorting规则。

我认为所有这些答案在正确的时候会误导这个问题。

实际的答案是在开始还原之前,如果您正在使用外键还原转储文件:

 SET FOREIGN_KEY_CHECKS=0; 

因为自然恢复会在外表甚至存在之前创build一些约束。

在某些情况下,如果相关表之间有不同的引擎,则可能会遇到此错误消息。 例如,一个表可能使用InnoDB,而另一个使用MyISAM。 两者都需要相同

错误号 150表示外键约束失败。 您可能在外键所依赖的表(表keywords )之前创build此表。 先创build表,它应该工作正常。

如果没有,则删除外键语句并在创build表后添加它 – 您将得到关于特定约束失败的更有意义的错误消息。

有时MySQL只是超级愚蠢 – 我可以理解外键的原因..但在我的情况下,我刚刚删除了整个数据库,我仍然得到错误…为什么? 我的意思是,没有数据库了…和我正在使用的SQL用户无法访问服务器上的任何其他数据库…我的意思是,服务器是“空”的当前用户,我仍然得到这个错误? 对不起,但我想MySQL是骗我…但我可以处理它:)只要在你的他妈的声明中添加这两行SQL:

 SET FOREIGN_KEY_CHECKS = 0; # some code that gives you errno: 150 SET FOREIGN_KEY_CHECKS = 1; 

现在的SQL应该被执行…如果你真的有一个外键的问题,它会显示给你的行,你将再次启用检查 – 这将失败,然后..但我的服务器只是安静:)

有很多事情可能导致errno 150,所以对于search这个话题的人来说,这里是我认为接近详尽的列表(errno 150的来源):

对于errno 150或errno 121,只需inputSHOW ENGINE INNODB STATUS,就会有一个名为“LATEST FOREIGN KEY ERROR”的部分。 在此之下,它会给你一个非常有用的错误信息,通常会告诉你什么事情。 你需要SUPER权限来运行它,所以如果你没有这个权限,你只需要testing下面的场景。

1)数据types不匹配:列的types必须相同

2)未索引父列(或以错误顺序索引)

3)列整理不匹配

4)在NOT NULL列上使用SET NULL

5)表sorting不匹配:即使列sorting匹配,在某些MySQL版本,这可能是一个问题。

6)父列实际上不存在于父表中。 检查拼写(也许在列的开头或结尾处有一个空格)

7)其中一列的其中一个索引不完整,或者列太长,无法获得完整的索引。 请注意,MySQL(除非你调整它)的最大单列密钥长度为767字节(这对应于一个varchar(255)UTF列)

如果你得到一个errno 121,这里有几个原因:

1)您select的约束名称已被使用

2)在某些系统中,如果您的语句和表名有区别。 如果你从一台服务器转到另一台有不同的情况处理规则的服务器,这可能会让你感到困扰。

150通常是一个外键错误。 你确定关键字表存在吗?

在浏览上面的答案之后,稍微尝试一下,这是解决MySQL中的外键错误(1005 – 错误150)的有效方法。

为了正确创build外键,所有MySQL要求的是:

  • 所有引用的键必须具有PRIMARY或UNIQUE索引。
  • 再次引用列必须与引用列具有相同的数据types。

满足这些要求,一切都会好起来的。

改变你的表的引擎,只有innoDB支持外键

如果在一个CHARSET中创buildPK表,然后在另一个CHARSET中创buildFK表,那么你也可能会得到这个错误…我也得到了这个错误,但是在把charset改成PK字符集之后,

 create table users ( ------------ ------------- )DEFAULT CHARSET=latin1; create table Emp ( --------- --------- --------- FOREIGN KEY (userid) REFERENCES users(id) on update cascade on delete cascade)ENGINE=InnoDB, DEFAULT CHARSET=latin1; 

如果两个表都有引用,则会发生此错误,例如,一个表是Student,另一个表是Education,我们希望Education表具有Student表的外键引用。 在这种情况下,两个表的列数据types应该是相同的,否则会产生错误。

在将Windows应用程序移植到Linux时遇到此错误。 在Windows中,数据库表名是不区分大小写的,在Linux中它们区分大小写,可能是因为文件系统的差异。 所以,在Windows表上, Table1是一样的,在REFERENCEStable1Table1起作用。 在Linux上,当应用程序使用table1而不是Table1创build数据库结构时,我看到错误#150; 当我在Table1引用中做出正确的字符大小写的时候,它也开始在Linux上工作了。 因此,如果没有其他帮助,请确保在REFERENCES中,当您在Linux上时,在表名中使用正确的字符大小写。

在大多数情况下,问题是由于ENGINE引起的。如果父代由InnoDB创build,那么引用的表应该由MyISAM创build,反之亦然

请确保您的主键列和引用列具有相同的数据types和属性(无符号,二进制,无符号的zerofill等)。

一个真正的边缘情况是你使用MySQL工具(Sequel Pro在我的情况)重命名一个数据库的地方。 然后创build一个同名的数据库。

这将外键约束保留到相同的数据库名称,所以重命名的数据库(例如my_db_renamed)在新创build的数据库(my_db)中具有外键约束,

不知道这是否是Sequel Pro中的错误,或者某些用例是否需要这种行为,但是这花费了我一大早的一部分:

我有同样的错误。 在我的情况下,错误的原因是,我在约束中有一个ON DELETE SET NULL语句,而我在其中定义约束的字段有一个NOT NULL语句。 在字段中允许NULL解决了这个问题。

在我的情况。 我有引擎和字符集的问题,因为我的主机服务器更改设置,我的新表是MyISAM,但我的旧表是InnoDB。 只是我改变了。

我有一个类似的问题,但是我的是因为我正在添加一个新的字段到有数据的现有表,新字段引用父表中的另一个字段,也有NOT NULL的定义,没有任何默认值。 – 我发现事情不起作用的原因是因为

  1. 在应用约束之前,我的新字段需要使用来自每个logging上的父表的值自动填充空白字段。 每次应用约束时,都需要保持表格数据的完整性。 实现约束(外键),但有一些数据库logging没有来自父表的值将意味着数据是腐败的,所以MySQL将永远不会强制你的约束

重要的是要记住,在正常情况下,如果您提前很好地规划了数据库,并且在数据插入之前实施了约束条件,则可以避免这种情况

避免这个问题的更简单的方法是

  • 保存您的数据库表数据
  • 截断表数据(和表工件,即索引等)
  • 应用约束
  • 导入您的数据

我希望这可以帮助别人

也许这会有帮助? 主键列的定义应该与外键列完全相同。

确保所有的表都可以支持外键 – InnoDB引擎

您从子表中引用的PARENT表的列必须是唯一的。 如果不是,则导致错误150。

当用一个表转储一个Django mysql数据库时,我遇到了类似的问题。 我能够通过将数据库转储到文本文件来解决问题,使用emacs将相关表移动到文件末尾,并将修改的sql转储文件导入到新实例中。

HTH Uwe

在从文本文件创build数据库时遇到这种问题。

 mysql -uroot -padmin < E:\important\sampdb\createdb.sql mysql -uroot -padmin sampdb < E:\important\sampdb\create_student.sql mysql -uroot -padmin sampdb < E:\important\sampdb\create_absence.sql mysql -uroot -padmin sampdb < E:\important\sampdb\insert_student.sql mysql -uroot -padmin sampdb < E:\important\sampdb\insert_absence.sql mysql -uroot -padmin sampdb < E:\important\sampdb\load_student.sql mysql -uroot -padmin sampdb < E:\important\sampdb\load_absence.sql 

我刚刚在Create.bat写了上面的Create.bat然后运行bat文件。

我的错误是在我的SQL文件中执行的顺序。 我试图用主键和外键创build表。 当它运行时,它将search参考表,但表不在那里。 所以它会返回这样的错误。

如果您使用外键创build表格,请检查参考表格是否存在。 还要检查参考表和字段的名称。

我已经通过使variables接受null纠正这个问题

 ALTER TABLE `ajout_norme` CHANGE `type_norme_code` `type_norme_code` VARCHAR( 2 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL 

执行一系列MySQL命令时,我遇到了同样的问题。 当创build一个表的时候,在引用一个外键的时候,这个外键还没有被创build。 引用之前的表存在的顺序。

解决scheme:在创build具有外键的子表之前先创build父表。

尝试:

 CREATE TABLE `data` ( `id` int(10) unsigned NOT NULL, `name` varchar(100) NOT NULL, `value` varchar(15) NOT NULL, UNIQUE KEY `id` (`id`,`name`), CONSTRAINT `data_ibfk_1`, FOREIGN KEY (`id`) REFERENCES `keywords` (`id`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=latin1; 

你需要在CONSTRAINTFOREIGN之间加一个“,”。