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 在模拟器上运行良好,但在设备上运行良好

为啥代码片段在 matplotlib 2.0.2 上运行良好,但在 matplotlib 2.1.0 上引发错误

旧版 MFC 应用程序在具有 Aero 主题的 windows7 操作系统上无法正常运行,但在经典主题下表现良好