SQL 代码在在线编译器上运行良好,但在 Linux 终端中由 MariaDB 编译时失败(错误号:150)
Posted
技术标签:
【中文标题】SQL 代码在在线编译器上运行良好,但在 Linux 终端中由 MariaDB 编译时失败(错误号:150)【英文标题】:SQL Code works fine on an online compiler but fails when compiled by MariaDB in Linux Terminal (errno: 150) 【发布时间】:2020-05-17 11:15:28 【问题描述】:搜索了论坛,尝试了一堆解决方案,但似乎没有任何效果。 下面是我使用的代码和在线编译器的小sn-p。
我得到(错误号:150“外键约束格式不正确”)。请注意,每当我尝试添加外键时,代码中的所有表都会出现此错误。
在线编译器:https://paiza.io/en/languages/mysql
代码:
-- CREATING AND INSERTING VALUES INTO THE BOOKINGS TABLE WITHOUT FK--
create table Bookings(
Booking_ID varchar(9) NOT NULL,
Client_ID varchar(6) NOT NULL,
PT_ID varchar(4) NOT NULL,
Booking_Date Date NOT NULL,
Start_Time time NOT NULL,
End_Time time NOT NULL,
Focus_ID varchar(3) NOT NULL,
Staff_ID varchar(4) NOT NULL,
PRIMARY KEY (Booking_ID)
);
INSERT INTO Bookings
VALUES
('B00000001','C00001','T001','2020-01-1','19:30:00','20:15:00','F01','S002'),
('B00000002','C00023','T001','2020-01-1','09:00:00','09:30:00','F02','S001'),
('B00000007','C00156','T003','2020-01-1','10:00:00','11:00:00','F04','S003');
-- CREATING AND INSERTING VALUES INTO THE CLIENT TABLE --
create table Client(
Client_ID varchar(6) NOT NULL,
Client_Name varchar(20) NOT NULL,
Height_cm decimal(5,2) NOT NULL,
Weight_kg decimal(6,2) NOT NULL,
Ph_Num varchar(14) NOT NULL,
PRIMARY KEY (Client_ID),
FOREIGN KEY (Client_ID)
REFERENCES Bookings(Client_ID)
);
-- ALTERING BOOKINGS TABLE WITH FOREIGN KEYS --
ALTER TABLE Bookings
ADD
FOREIGN KEY (Client_ID)
REFERENCES Client(Client_ID);
正如我在标题中提到的,代码在网上运行良好,但在 Linux 终端上通过 MariaDB 编译时失败。
MariaDB 服务器版本为 10.3.17-MariaDB
我做错了什么?任何帮助将不胜感激。
【问题讨论】:
你用的是什么存储引擎? 请原谅我,因为我对 sql 还很陌生,但什么是存储引擎,如何找到它? 您不需要在两个表上创建外键,只需在 Bookings 表中引用 Clients 表的那个。外键引用另一个表的主键。因此,您从 Clients 到 Bookings 的外键无效,因为 Client_ID 不是 Bookings 的主键。 @drakin8564 这就是修复它的原因,谢谢!我一直觉得两个表都需要外键很奇怪! 150:更改表的声明顺序 OR 在创建表之前禁用,然后在创建所有表后重新启用 OR 应用所有 FK . 【参考方案1】:好吧,关于存储引擎,我首先要说的是,并非所有存储引擎都支持外键约束。
存储引擎是管理表和数据的系统,有多种存储引擎可用,例如:MyISAM 或 InnoDb。 (默认来自 MySQL 5.6 InnoDB)
每个存储引擎都有自己的特性和独特的特性,可以在特定情况下使用。大多数时候你并不“关心”存储引擎,除非你想使用一些特定的功能。
如果您不确定选择哪个存储引擎,请坚持使用默认值并使用InnoDB
有关存储引擎的更多信息,请查看 MySQL 参考手册。 (如果您想学习和理解,我强烈建议您这样做)
https://dev.mysql.com/doc/refman/8.0/en/innodb-introduction.html https://dev.mysql.com/doc/refman/8.0/en/myisam-storage-engine.html
我认为问题在于 Bookings 上的 Client_ID
列不是索引字段。
如果我更改表定义并为其添加一个 INDEX 约束,那么一切正常。
create table Bookings( Booking_ID varchar(9) NOT NULL, Client_ID varchar(6) NOT NULL, PT_ID varchar(4) NOT NULL, Booking_Date Date NOT NULL, Start_Time time NOT NULL, End_Time time NOT NULL, Focus_ID varchar(3) NOT NULL, Staff_ID varchar(4) NOT NULL, PRIMARY KEY (Booking_ID), INDEX (Client_ID) );
INSERT INTO Bookings
VALUES
('B00000001','C00001','T001','2020-01-1','19:30:00','20:15:00','F01','S002'),
('B00000002','C00023','T001','2020-01-1','09:00:00','09:30:00','F02','S001'),
('B00000007','C00156','T003','2020-01-1','10:00:00','11:00:00','F04','S003');
create table Client(
Client_ID varchar(6) NOT NULL,
Client_Name varchar(20) NOT NULL,
Height_cm decimal(5,2) NOT NULL,
Weight_kg decimal(6,2) NOT NULL,
Ph_Num varchar(14) NOT NULL,
PRIMARY KEY (Client_ID),
FOREIGN KEY (Client_ID)
REFERENCES Bookings(Client_ID)
);
【讨论】:
【参考方案2】:前面的答案是正确的。
MariaDB 要求引用的列是 PK 或索引的(最好是唯一索引的)。
如果添加索引不能帮助解决问题,请检查您的默认存储引擎,看看它是否设置为 MyISAM 而不是 InnoDB。
显示全局变量,如“%storage%”;
【讨论】:
【参考方案3】:如果您附加例如show create table Bookings;
在你得到的脚本末尾:
CREATE TABLE `Bookings` ([…]) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4
^^^^^^^^^^^^^
这意味着 https://paiza.io 被配置为使用 MyISAM 作为默认引擎,因此当您自己不设置任何引擎时,您会得到这样的结果。确保在您的代码中设置ENGINE=InnoDB
,这样您就不会忽略外键。
【讨论】:
以上是关于SQL 代码在在线编译器上运行良好,但在 Linux 终端中由 MariaDB 编译时失败(错误号:150)的主要内容,如果未能解决你的问题,请参考以下文章
Javascript未在在线网站上加载,但在本地加载xampp
Xmppframework for iphone 在模拟器上运行良好,但在设备上运行不正常?
代码在 Linux 上运行良好,但在 Windows 操作系统上给出不同的输出
NSFileManager 在模拟器上运行良好,但在设备上运行良好