mysql - 使用复合主键作为外键

标签 mysql sql

我一直认为,如果我要使用引用复合主键的外键,我需要在两个表中包含复合主键的所有列。

当我无意中没有这样做并且没有收到任何错误时,我很困惑。在下面的示例中,RoomId 不是唯一的,但它本身可以用作外键。

CREATE TABLE Buildings (
BuildingName VARCHAR(4) PRIMARY KEY,
CampusId TINYINT,
StreetAddress VARCHAR(50),
City VARCHAR(30),
State CHAR(2),
Zip CHAR(5)
);

CREATE TABLE Rooms (
RoomId VARCHAR(5),
BuildingName VARCHAR(20) NOT NULL,
RoomType VARCHAR(15),
Capacity INT,
Notes VARCHAR(100),
CONSTRAINT FK_Buildings_Rooms FOREIGN KEY (BuildingName) REFERENCES Buildings(BuildingName),
PRIMARY KEY (RoomId, BuildingName)
);

CREATE TABLE Instructors(
EmployeeId INT AUTO_INCREMENT PRIMARY KEY,
OfficeId VARCHAR(5),
CONSTRAINT Fk_Instructors_Rooms FOREIGN KEY (OfficeId) REFERENCES Rooms(RoomId));

如果我将复合主键中的顺序切换为 (BuildingName, RoomId),则外键声明会产生预期的错误: 错误代码:1822。无法添加外键约束。引用表“rooms”中缺少约束“Fk_Instructors_Rooms”的索引

最佳答案

MySQL 扩展了外键的传统定义。在大多数数据库中,它们仅限于唯一键或主键。与其他一些“扩展”一样,documentation明确警告不要引用非唯一键:

However, the system does not enforce a requirement that the referenced columns be UNIQUE or be declared NOT NULL. The handling of foreign key references to nonunique keys or keys that contain NULL values is not well defined for operations such as UPDATE or DELETE CASCADE. You are advised to use foreign keys that reference only UNIQUE (including PRIMARY) and NOT NULL keys.

当然,不包括复合键的所有组件意味着您使用的是非唯一键。

您的复合主键问题很有趣。就个人而言,我会把它归结为使用自动递增主键的另一个原因。单列在外键声明中不太容易出错。

关于mysql - 使用复合主键作为外键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58276099/

相关文章:

html - 使用 MySQL 查找 HTML 中的电子邮件链接

php - 2个不同表的SQL查询

php - 删除 mysql 中的行并从文件夹关联

mysql - 根据日期部分将一行取消分组为多行

mysql - 通过具有良好性能的唯一列选择多行

MySQL:如何将 varchar(255) UNIQUE 列更改为 UNIQUE Text NOT NULL?

SQL JOIN 两个表

php - 并非所有数据都在显示

sql - 在mysql中左连接右表的条件

php - 如何将 youtube 嵌入链接存储在数据库中