MySQL外键,无法创建表(错误号:150)

11

我正在尝试为我的系统构建数据库和表格。但是我发现,如果我在代码中不添加外键,则不会出现错误。我已经尝试过很多方法来使代码工作,但它仍然存在错误。

我正在使用MySQL 5.5.31,这里是代码:CREATE DATABASE TOS;

DROP TABLE TOS.USER CASCADE;
DROP TABLE TOS.BILL_HEADER CASCADE;
DROP TABLE TOS.TOY CASCADE;


CREATE TABLE TOS.USER
(User Char(8),
Name Char(10),
Type Char(1),
Password Char(12),
PRIMARY KEY(User));

CREATE TABLE TOS.BILL_HEADER
(Bill_No Char(10),
CTime DateTime,
No_Of INTEGER,
Cus_No Char(5),
DTime DateTime,
PRIMARY KEY(Bill_No));

CREATE TABLE TOS.TOY
(Toy_Id Char(10),
FullN Char(50),
ShortN Char(20),
Descrip Char(20),
Price DECIMAL,
Avail Char(1),
Cat Char(1),
PRIMARY KEY(Toy_Id));

CREATE TABLE TOS.BILL_ITEM
(Bill_No Char(10),
BSeq_No INTEGER,
Toy_Id Char(10),
OTime DateTime,
Quan INT,
DCondition Char(1),
PRIMARY KEY(Bill_No,BSeq_No),
FOREIGN KEY(Bill_No) REFERENCES TOS.Bill_Header(Bill_No),
FOREIGN KEY(Toy_Id) REFERENCES TOS.TOY(Toy_Id));

错误:

1005 - 无法创建表 'TOS.BILL_ITEM' (errno: 150)

任何帮助将不胜感激。


如果我删除 DROP 语句似乎可以正常工作。http://sqlfiddle.com/#!2/08d1e - Michael Berkowski
2
通常,err 150 是外键错误,由于列和关系之间的数据类型和长度不匹配,或者主列上缺少索引。虽然您已经定义了所有正确的类型和 PK 索引。 - Michael Berkowski
你能试着移除其中一个外键来缩小问题范围吗? - Oscar Pérez
2个回答

19

非描述性错误150通常与外键数据类型或长度不匹配,或父表列上缺少索引有关。

这似乎是表名大小写敏感的问题Bill_Header(应为BILL_HEADER)。
来自MySQL标识符大小写敏感性文档:

  

在MySQL中,数据库对应于数据目录中的目录。数据库中的每个表对应于数据库目录中的至少一个文件(可能更多,具体取决于存储引擎)。因此,底层操作系统的大小写敏感性对数据库和表名的大小写敏感性起作用。这意味着在Windows中数据库和表名不区分大小写,在大多数Unix变体中区分大小写。

修正大小写后应该可以正常工作:

CREATE TABLE TOS.BILL_ITEM
(Bill_No Char(10),
BSeq_No INTEGER,
Toy_Id Char(10),
OTime DateTime,
Quan INT,
DCondition Char(1),
PRIMARY KEY(Bill_No,BSeq_No),
FOREIGN KEY(Bill_No) REFERENCES TOS.BILL_HEADER(Bill_No),
# Here-----------------------------^^^^^^^^^^^^^^
FOREIGN KEY(Toy_Id) REFERENCES TOS.TOY(Toy_Id));

由于您的代码在SQLFiddle.com (http://sqlfiddle.com/#!2/08d1e) 上能够正常工作,因此该平台不区分大小写。


3
在我的情况下,父表和子表之间存在字段排序规则不匹配的问题。 - Serge
2
另一个微妙的问题是字符集必须匹配。我刚遇到这个问题,我引用的表是utf8,但它试图在latin-1表上创建新的约束。一旦我在创建表中指定了ut8,一切都很好。 - Felix
还要检查外键字段上的有符号和无符号不匹配问题。 - stantonk

9
上面的答案是正确的,但如果您的外键引用的表是MyISAM而不是InnoDB,则也可能会出现此错误。

或者,如果父表已指定DEFAULT CHARSET,而子表未指定或指定了不同的DEFAULT CHARSET。 - Sean Colombo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接