SQL 1005错误的麻烦(错误150)

时间:2016-04-28 23:59:40

标签: mysql database foreign-keys

我和其他许多人一样,在mySQL中与臭名昭着的errno 150挣扎。我知道它与外键有关,我知道关于这个问题已经有很多问题了,但是在花了大量时间寻找解决方案后,我还没找到一个适合我的具体案例。几乎每个错误都是在这个旅行数据库中完成的,但最后一个错误是在尝试创建一个名为leg的表时产生的。我将在与此相关的表格下方发布。

CREATE TABLE ticket(
id int UNSIGNED NOT NULL,
passenger_id int UNSIGNED,
trip_id int UNSIGNED,
leg_no int UNSIGNED,
purchased_on datetime,
reservation_date date,
PRIMARY KEY(id),
CONSTRAINT fk_ticket_passenger_id_passenger FOREIGN KEY
(passenger_id) REFERENCES passenger(id),
CONSTRAINT fk_ticket_trip_id_trip FOREIGN KEY
(trip_id) REFERENCES trip(id),
CONSTRAINT fk_ticket_leg_no_leg FOREIGN KEY
(leg_no) REFERENCES leg(leg_no));

CREATE TABLE trip(
id int UNSIGNED NOT NULL,
number_of_legs int UNSIGNED,
PRIMARY KEY(id));

CREATE TABLE leg(
trip_id int UNSIGNED NOT NULL,
leg_no int UNSIGNED NOT NULL,
origin_id int UNSIGNED,
destination_id int UNSIGNED,
depart_time time,
arrive_time time,
vdesignation varchar(255),
price decimal(13,2),
PRIMARY KEY(trip_id, leg_no),
CONSTRAINT fk_leg_trip_id_trip FOREIGN KEY
(trip_id) REFERENCES trip(id),
CONSTRAINT fk_leg_vdesignation_vehicle FOREIGN KEY
(vdesignation) REFERENCES vehicle(designation),
CONSTRAINT fk_leg_origin_id_island FOREIGN KEY
(origin_id) REFERENCES island(id),
CONSTRAINT fk_leg_destination_id_island FOREIGN KEY
(destination_id) REFERENCES island(id));

CREATE TABLE vehicle(
designation varchar(255) NOT NULL,
vtype varchar(255),
capacity int UNSIGNED,
PRIMARY KEY(designation));

CREATE TABLE island(
id int UNSIGNED NOT NULL,
iname varchar(255),
can_fly tinyint UNSIGNED,
PRIMARY KEY(id));

我知道这个问题被问了很多,我确信它会变老,我会非常感谢你对我提出的任何建议。我已经彻底搜索了解决方案,似乎无法弄明白。提前感谢您提供给我的任何信息!

编辑:以下是错误的具体警告信息:

*************************** 1. row ***************************
Level: Error
Code: 1005
Message: Can't create table 'travel.leg' (errno: 150)
1 row in set (0.04 sec)

编辑2:添加了车辆表以回应第一个答案,因为我忘了首先添加它。

2 个答案:

答案 0 :(得分:0)

我在leg表中看到了外键的两个潜在问题:

1。第一个问题是使用fk_leg_vdesignation外键

CONSTRAINT fk_leg_vdesignation_vehicle FOREIGN KEY (vdesignation)
    REFERENCES vehicle(designation)

您从未向我们展示vehicle表格,因此我们无法验证其中designation列的类型与leg.vdesignation相同,即varchar(255)。如果类型不匹配,或者vehicle.designation不存在,您应该会看到150错误。

2。 leg中的以下两个外键似乎都引用了island表中的同一列:

CONSTRAINT fk_leg_origin_id_island FOREIGN KEY (origin_id) REFERENCES island(id)
CONSTRAINT fk_leg_destination_id_island FOREIGN KEY (destination_id) REFERENCES island(id)

我没有看到同时拥有它们的意义。此外,leg.origin_idleg.destination_id的类型为int UNSIGNED,而外国列island.id的类型为int UNSIGNED NOT NULL。由于类型不完全相同,这可能导致错误150。

答案 1 :(得分:0)

我最终通过一阵突然的直觉搞清楚了。问题实际上来自ticket表。为了解决这个问题,我结合了表的最后两个外键。这意味着我改变了我的约束:

CONSTRAINT fk_ticket_trip_id_trip FOREIGN KEY
(trip_id) REFERENCES trip(id),
CONSTRAINT fk_ticket_leg_no_leg FOREIGN KEY
(leg_no) REFERENCES leg(leg_no));

对此:

CONSTRAINT fk_ticket_leg_no_leg FOREIGN KEY
(trip_id, leg_no) REFERENCES leg(trip_id, leg_no));

我对错误的理解是外键应该引用另一个表的主键。当两个外键中的第二个引用leg.leg_no时,它只是指键的一部分。 leg.leg_no是主键的主要属性,但它本身无法识别表的特定行,因此它将无法正常作为外键引用。

无论如何,谢谢蒂姆的帮助!如果没有你关于有两个外键的注释引用相同的键,我可能从来没有想过这个。