sql - 多对多关系表的约束——两个相关记录都需要引用相同的依赖记录?
问题描述
共有三个实体Student
,Class
和 Department
。部门和学生具有一对多的关系。部门和班级也有一对多的关系。Student 和 Class 是多对多的关系。
create table Department
(
Id int primary key,
-- ...
)
create table Student
(
Id int primary key,
DepartmentId int not null references Department(Id),
-- ....
)
create table Class
(
Id int primary key,
DepartmentId int not null references Department(Id),
....
)
下表是学生和班级之间的多对多关系。现在用户可以将一对来自不同(不应该允许的)部门的学生/班级放在表中。除了使用触发器之外,这是一种防止它的方法吗?
create table StudentAndClass
(
StudentId int references Student(Id),
ClassId int references Class(Id),
-- ....
primary key (StudentId, ClassId)
)
解决方案
您可以在没有触发器或特殊功能的情况下执行此操作。这个想法是使用外键关系。. . 通过定义一组额外的键并DepartmentId
(冗余地)添加到联结表:
create table Students (
StudentId int primary key,
DepartmentId int not null references Department(Id),
-- ....
unique (DepartmentId, StudentId)
);
create table Classes (
ClassId int primary key,
DepartmentId int not null references Department(Id),
....
unique (DepartmentId, ClassId)
);
create table StudentClasses (
DepartmentId int references Department(DepartmentId),
StudentId int,
ClassId int,
-- ....
primary key (StudentId, ClassId),
foreign key (DepartmentId, StudentId) references (DepartmentId, StudentId),
foreign key (DepartmentId, ClassId) references (DepartmentId, ClassId),
);
您可能不想要冗余,但没有触发器或特殊功能是可能的。
推荐阅读
- ios - 将主页图标添加到标签栏
- angularjs - scope.$on $mdMenuOpen 不起作用
- ruby-on-rails - 如何在rails中压缩JS数据
- python-2.7 - python - 检查文件夹中是否存在任何.jpg文件,如果不存在则等待
- file - 同一操作系统中的两个文件系统之间的文件大小可以不同吗?
- ios - Firebase 嵌套解析 Swift
- r - R Shiny 应用程序:使用传单弹出窗口创建指向新仪表板窗口的超链接
- android - 用户 10093 和当前进程在 Android M 中都没有 android.permission.READ_PHONE_STATE 错误
- python - ImportError:无法导入名称“solve_ivp”
- lotus-domino - IBM Domino:合并来自两个数据库的 NotesDocument