sql - MySQL:无法创建表(错误号:150)
我试图导入.sql文件,并在创建表时失败。
这是失败的查询:
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:无法创建表'./dbname/data.frm'(错误号:150)
30个解决方案
160 votes
从MySQL - FOREIGN KEY约束文档:
如果重新创建已删除的表,则它必须具有符合引用它的外键约束的定义。 它必须具有正确的列名和类型,并且必须在引用的键上具有索引,如前所述。 如果不满足这些,MySQL将返回错误1005并在错误消息中引用错误150,这意味着未正确形成外键约束。 类似地,如果ALTER TABLE由于错误150而失败,则意味着对于更改的表将错误地形成外键定义。
OMG Ponies answered 2019-05-11T08:28:24Z
95 votes
错误150表示您的外键有问题。 可能外表上的键不是完全相同的类型?
Dan McGrath answered 2019-05-11T08:28:48Z
56 votes
您可以通过运行SHOW ENGINE INNODB STATUS;然后在输出中查找LATEST FOREIGN KEY ERROR来获取实际的错误消息。
来源:在类似问题中来自其他用户的回答
Denilson Sá Maia answered 2019-05-11T08:29:20Z
27 votes
数据类型必须完全匹配。 如果要处理varchar类型,则表必须使用相同的排序规则。
Esben Skov Pedersen answered 2019-05-11T08:29:45Z
24 votes
我认为正确的所有这些答案都会误导这个问题。
如果要使用外键还原转储文件,则在开始还原之前,实际答案是:
SET FOREIGN_KEY_CHECKS=0;
因为在外表甚至存在之前,恢复自然会创建一些约束。
colin answered 2019-05-11T08:30:24Z
19 votes
在某些情况下,如果相关表之间存在不同的引擎,则可能会遇到此错误消息。 例如,表可能正在使用InnoDB而另一个表使用MyISAM。 两者都需要相同
pi. answered 2019-05-11T08:30:48Z
11 votes
错误号码 150表示外键约束失败。 您可能在外键所依赖的表之前创建此表(表keywords)。 首先创建该表,它应该工作正常。
如果没有,删除外键语句并在创建表后添加它 - 您将获得有关特定约束失败的更有意义的错误消息。
Eran Galperin answered 2019-05-11T08:31:21Z
10 votes
有很多事情可以导致errno 150,所以对于搜索这个主题的人来说,这是我认为接近详尽的列表(Errno 150的来源):
对于errno 150或errno 121,只需键入SHOW ENGINE INNODB STATUS,就会出现一个名为“LATEST FOREIGN KEY ERROR”的部分。 在此之下它会给你一个非常有用的错误信息,通常会立即告诉你什么是问题。 您需要SUPER权限才能运行它,因此如果您没有,则只需测试以下方案即可。
1)数据类型不匹配:列的类型必须相同
2)没有索引的父列(或以错误的顺序索引)
3)列排序不匹配
4)在NOT NULL列上使用SET NULL
5)表排序不匹配:即使列排序匹配,在某些MySQL版本上这可能是个问题。
6)父列在父表中实际上不存在。 检查拼写(也许是列的开头或结尾处的空格)
7)其中一列的索引之一是不完整的,或者列对于完整索引而言太长。 请注意,MySQL(除非您调整它)的最大单列密钥长度为767字节(这对应于varchar(255)UTF列)
如果你得到一个errno 121,这里有几个原因:
1)您选择的约束名称已被采用
2)在某些系统上,如果语句和表名中存在大小写差异。 如果您从一台服务器转到另一台具有不同案例处理规则的服务器,这可能会让您感到困惑。
juacala answered 2019-05-11T08:33:07Z
8 votes
有时MySQL只是超级愚蠢 - 我可以理解外键的原因..但在我的情况下,我刚刚删除整个数据库,我仍然得到错误...为什么? 我的意思是,没有数据库了......我正在使用的sql-user无法访问服务器上的任何其他数据库......我的意思是,服务器对于当前用户来说是“空的”而且我仍然得到 这个错误? 抱歉,我想MySQL对我说谎......但我可以处理它:)只需在你的fucky语句中添加这两行SQL:
SET FOREIGN_KEY_CHECKS = 0;
# some code that gives you errno: 150
SET FOREIGN_KEY_CHECKS = 1;
现在应该执行sql ...如果你真的有一个外键问题,它将显示你将再次启用检查的行 - 这将失败然后..但我的服务器只是安静:)
jebbie answered 2019-05-11T08:33:40Z
4 votes
在完成上述答案并进行实验后,这是解决MySQL中外键错误的有效方法(1005 - 错误150)。
要正确创建外键,MySQL要求的是:
所有引用的键必须具有PRIMARY或UNIQUE索引。
再次引用列必须具有与Referenced列相同的数据类型。
满足这些要求,一切都会好起来的。
Davies Malesi answered 2019-05-11T08:34:33Z
4 votes
将Windows应用程序移植到Linux时遇到此错误。 在Windows中,数据库表名称不区分大小写,在Linux中它们区分大小写,可能是因为文件系统不同。 因此,在Windows上,表Table1与table1相同,并且在REFERENCES中,table1和Table1均可正常工作。 在Linux上,当应用程序在创建数据库结构时使用table1而不是Table1时,我看到错误#150; 当我在Table1引用中创建了正确的字符大小写时,它也开始在Linux上运行。 因此,如果没有别的帮助,请确保在REFERENCES中使用Linux时在表名中使用正确的字符大小写。
Vitaliy answered 2019-05-11T08:35:03Z
3 votes
更改表的引擎,只有innoDB支持外键
Lappies answered 2019-05-11T08:35:30Z
3 votes
如果PK表是在一个CHARSET中创建的,然后你在另一个CHARSET中创建FK表..那么你也可能会收到此错误...我也得到了这个错误但是在将charset更改为PK charset后它被执行而没有错误
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;
tinku answered 2019-05-11T08:35:58Z
3 votes
如果两个表具有引用,则会发生此错误,例如,一个表是Student,另一个表是Education,并且我们希望Education表具有Student表的外键引用。 在这种情况下,两个表的列数据类型应该相同,否则会生成错误。
manzarul haque answered 2019-05-11T08:36:27Z
3 votes
在大多数情况下,问题是由于引擎dIfference。如果父项是由InnoDB创建的,那么引用的表应该由MyISAM& AM创建。 反之亦然
Sunil Kumar Mohanty answered 2019-05-11T08:36:55Z
3 votes
就我而言。 我的引擎和字符集有问题因为我的托管服务器更改设置而我的新表是MyISAM但我的旧表是InnoDB。 我改变了。
Ignacio Hernández answered 2019-05-11T08:37:23Z
3 votes
我有同样的问题。 它与表的列Collation和Character Set有关。确保两个表上的两列的字符集和排序规则必须相同。 如果要在其上设置外键。示例 - 如果将外键放在userImage表的userID列上,引用users表的userID列。那么对于两列表,Collation必须与utf8_general_ci和字符集utf8相同。 通常,当您创建表时,mysql会从服务器设置中获取这两个配置。
Sushilkumar answered 2019-05-11T08:37:52Z
2 votes
请确保主键列和引用列都具有相同的数据类型和属性(无符号,二进制,无符号zerofill等)。
Basit answered 2019-05-11T08:38:20Z
2 votes
一个真实的边缘案例是你使用MySQL工具(在我的例子中是Sequel Pro)来重命名数据库。 然后创建一个具有相同名称的数据库。
这将外键约束保留在同一个数据库名称中,因此重命名的数据库(例如my_db_renamed)在新创建的数据库(my_db)中具有外键约束
不确定这是否是Sequel Pro中的错误,或者某些用例需要这种行为,但它在早上花费了我最好的部分:/
chim answered 2019-05-11T08:39:03Z
2 votes
我有同样的错误。 在我的情况下,错误的原因是我在约束中有一个ON DELETE SET NULL语句,而我在其定义中放置约束的字段有一个NOT NULL语句。 在字段中允许NULL解决了问题。
Wilbert van Diemen answered 2019-05-11T08:39:31Z
2 votes
我有一个类似的问题,但我的是因为我在一个有数据的现有表中添加了一个新字段,并且新字段引用了父表中的另一个字段,并且还具有NOT NULL的定义且没有任何默认值。 - 我发现事情不起作用的原因是因为
在应用约束之前,我的新字段需要使用每个记录上的父表的值自动填充空白字段。 每次应用约束时,都需要保持表数据的完整性。 实现约束(外键)但是有一些数据库记录没有来自父表的值意味着数据已损坏,所以MySQL永远不会强制你的约束
重要的是要记住,在正常情况下,如果您提前计划好数据库,并在数据插入之前实施约束,则应避免此特定方案
更容易避免这种问题的方法是
保存数据库表数据
截断表数据(和表工件,即索引等)
应用约束
导入您的数据
我希望这可以帮助别人
chitwarnold answered 2019-05-11T08:40:57Z
2 votes
通常,外键和外键之间的不匹配 主键导致 错误:150。
外键必须与主键具有相同的数据类型。 此外,如果主键是无符号的,则外键也必须是无符号的。
Rakesh answered 2019-05-11T08:41:32Z
1 votes
也许这会有所帮助吗? 主键列的定义应与外键列完全相同。
Mukus answered 2019-05-11T08:42:00Z
1 votes
确保所有表都支持外键 - InnoDB引擎
joksy82 answered 2019-05-11T08:42:28Z
1 votes
您从子表中引用的PARENT表的列必须是唯一的。 如果不是,则导致错误否150。
Dila Ram Gurung answered 2019-05-11T08:42:56Z
1 votes
使用单个表转储Django mysql数据库时遇到了类似的问题。 我能够通过将数据库转储到文本文件,使用emacs将有问题的表移动到文件末尾并将修改后的sql转储文件导入新实例来解决问题。
HTH Uwe
hoover answered 2019-05-11T08:43:30Z
1 votes
我从文本文件创建数据库时遇到了这种问题。
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中编写了上述行并运行了bat文件。
我的错误是在我的sql文件中执行的顺序。 我试图用主键和外键创建表。 在运行时,它将搜索引用表,但表不存在。所以它会返回那种错误。
如果使用外键创建表,请检查引用 桌子是否存在。 并检查参考的名称 表格和字段。
Dharani Dharan answered 2019-05-11T08:44:23Z
1 votes
我通过使变量接受null纠正了这个问题
ALTER TABLE `ajout_norme`
CHANGE `type_norme_code` `type_norme_code` VARCHAR( 2 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL
Fahmi answered 2019-05-11T08:44:52Z
1 votes
我在执行一系列MySQL命令时遇到了同样的问题。 在将外键引用到尚未创建的其他表时,在创建表期间发生。 它是引用之前表的序列。
解决方案:在创建具有外键的子表之前,首先创建父表。
ronIT answered 2019-05-11T08:45:28Z
1 votes
创建没有外键的表,然后分别设置外键。
stuckhelper answered 2019-05-11T08:45:59Z