使用复合主键作为外键

时间:2019-10-07 19:37:46

标签: mysql sql

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

当我无意间没有这样做并且没有收到任何错误时,我感到困惑。在下面的示例中,RoomId ISN不是唯一的,但允许其单独用作外键。

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),则外键声明会产生预期的错误: Error Code: 1822. Failed to add the foreign key constraint. Missing index for constraint 'Fk_Instructors_Rooms' in the referenced table 'rooms'

2 个答案:

答案 0 :(得分:1)

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

  

但是,系统不强制要求引用的列为UNIQUE或声明为NOT NULL。对于诸如UPDATE或DELETE CASCADE之类的操作,未很好地定义对非唯一键或包含NULL值的键的外键引用的处理。 建议您使用仅引用UNIQUE(包括PRIMARY)和NOT NULL键的外键。

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

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

答案 1 :(得分:0)

外键不需要引用唯一或主键字段。他们可以引用任何索引(主索引,唯一索引或纯索引)的第一个字段。