我想问一下我遇到的一个特定问题。
例如,我有一个Student
表,其中包含SchoolID
和ClassID
,这两个表都是School
和Classroom
的外键分别表。 Class
表有一个SchoolID
列,它是School
表的外键。
有什么方法可以确保ClassID
表格中的Student
是SchoolID
的孩子,或者我必须删除SchoolID
才能确定ClassID
是为了防止出现任何可能的差异?
答案 0 :(得分:1)
是的,从技术上讲,如果Class已经有Student.SchoolId
,那么您应该删除SchoolId
外键,因为这已经定义了Student
和School
之间的关系。
也就是说,有一些常见的“例外”,例如:
如果Student
和School
之间的关系可能与Class
和School
之间的关系有所不同(例如,如果学生去学校X时'他/她的主要学校',但随后还在Z学校参加额外的Y级壁画。 (实际上,这可能会突出显示建模错误,即Student:Class实际上可能是多对多的关系)
出于性能原因,有时(有点不情愿)选择将父母的外键添加到子节点以避免需要加入父节点。但正如您所说,这可能导致完整性问题。
答案 1 :(得分:1)
是的,您可以通过在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
列中声明外键 。
答案 2 :(得分:0)
学生表应该引用Class。
create table Student (
...
SchoolID integer not null,
ClassID integer not null,
foreign key (SchoolID, ClassID) references Class (SchoolID, ClassID),
...
);
反过来,Class表应该引用School。