1

我想问一下我遇到的一个特定问题。

例如,我有一个Student具有 aSchoolID和 a的表,它们分别是 the和表ClassID的外键。该表有一列是该表的外键。SchoolClassroomClassSchoolIDSchool

有什么办法可以确保表格中ClassIDStudent是 的孩子SchoolID,还是我必须删除SchoolID并与 一起生活ClassID以防止任何可能的差异?

4

3 回答 3

2

Student.SchoolId是的,从技术上讲,如果 Class 已经有,您应该删除外键,因为这已经定义了andSchoolId之间的关系。StudentSchool

也就是说,有一些常见的“例外”,例如:

  1. 如果和之间的关系可能意味着Student与和School之间的关系不同的东西ClassSchool例如,如果学生作为“他/她的主要学校”去学校 X,但随后还在学校 Z 上额外的壁画 Y 班)。(实际上,这可能会突出一个建模错误,即 Student : Class 实际上可能是多对多关系)

  2. 出于性能原因,有时(有点不情愿)选择将父级的外键添加到子级以避免需要重新加入父级。但正如您所说,这可能会导致完整性问题。

于 2012-08-21T08:46:34.187 回答
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

于 2012-08-21T08:49:59.450 回答
0

Student 表应该引用 Class。

create table Student (
  ...
  SchoolID integer not null,
  ClassID integer not null,
  foreign key (SchoolID, ClassID) references Class (SchoolID, ClassID),
  ...
);

反过来,Class 表应该引用 School。

于 2012-08-21T08:46:44.757 回答