我想问一下我遇到的一个特定问题。
例如,我有一个Student
具有 aSchoolID
和 a的表,它们分别是 the和表ClassID
的外键。该表有一列是该表的外键。School
Classroom
Class
SchoolID
School
有什么办法可以确保表格中ClassID
的Student
是 的孩子SchoolID
,还是我必须删除SchoolID
并与 一起生活ClassID
以防止任何可能的差异?
我想问一下我遇到的一个特定问题。
例如,我有一个Student
具有 aSchoolID
和 a的表,它们分别是 the和表ClassID
的外键。该表有一列是该表的外键。School
Classroom
Class
SchoolID
School
有什么办法可以确保表格中ClassID
的Student
是 的孩子SchoolID
,还是我必须删除SchoolID
并与 一起生活ClassID
以防止任何可能的差异?
Student.SchoolId
是的,从技术上讲,如果 Class 已经有,您应该删除外键,因为这已经定义了andSchoolId
之间的关系。Student
School
也就是说,有一些常见的“例外”,例如:
如果和之间的关系可能意味着Student
与和School
之间的关系不同的东西Class
(School
例如,如果学生作为“他/她的主要学校”去学校 X,但随后还在学校 Z 上额外的壁画 Y 班)。(实际上,这可能会突出一个建模错误,即 Student : Class 实际上可能是多对多关系)
出于性能原因,有时(有点不情愿)选择将父级的外键添加到子级以避免需要重新加入父级。但正如您所说,这可能会导致完整性问题。
是的,您可以通过在表的外键引用中有多个列来强制执行它Classes
:
create table Schools (
SchoolID int not null primary key,
Name varchar(30) not null unique
)
go
create table Classes (
ClassID int not null primary key,
SchoolID int not null foreign key references Schools (SchoolID),
Name varchar(30) not null,
constraint UQ_Class_Schools UNIQUE (ClassID,SchoolID),
constraint UQ_Class_Names UNIQUE (SchoolID,Name)
)
go
create table Students (
StudentID int not null primary key,
SchoolID int not null foreign key references Schools (SchoolID),
ClassID int not null,
Name varchar(95) not null,
constraint FK_Student_Classes FOREIGN KEY (ClassID,SchoolID) references Classes (ClassID,SchoolID)
)
根据口味,您可能还决定在两个表中的列上也声明一个外键。ClassID
Student 表应该引用 Class。
create table Student (
...
SchoolID integer not null,
ClassID integer not null,
foreign key (SchoolID, ClassID) references Class (SchoolID, ClassID),
...
);
反过来,Class 表应该引用 School。