SQL 共同归属的数据库设计约束
SQL db design constraints for co-belonging
这是我的数据库结构,它包含 3 tables : School, Student, Course
每个学生都必须属于一所学校(因此学校 ID 将是学生 table 中引用学校 table 的外键)。
每门课程还必须属于一所学校(因此学校 ID 将是课程 table 中指向学校 table 的外键)。
最后,每个学生可以注册一门或多门课程(pivot table 学生有一个外键,学校有一个外键),但有一个限制,即学生和课程都必须属于同一所学校。不允许学生报名参加与学生属于不同学校的课程。
有没有办法在枢轴 table 中添加此约束,或者以其他方式对其建模?
还是应该在每次插入主元之前在代码中强制执行约束 table?
您可以将 SchoolID 作为主键的一部分添加到学生和课程中。
这将强制那些 table 的外键也指定 SchoolID。
我们在 StudentInCourse-table 中使用这个事实来强制学生和课程都属于同一所学校。
CREATE TABLE School(id INT PRIMARY KEY);
CREATE TABLE Course(id int, schoolID INT
FOREIGN KEY REFERENCES dbo.School(id),
PRIMARY KEY(id, schoolID));
CREATE TABLE Student(id INT, schoolID INT
FOREIGN KEY REFERENCES dbo.School(id),
PRIMARY KEY(id, SchoolID));
CREATE TABLE StudentInCourse(StudentId INT, schoolId INT, CourseID INT,
CONSTRAINT [fk_student]
FOREIGN KEY (StudentId,schoolID) REFERENCES student(id, SchoolID),
CONSTRAINT [fk_course]
FOREIGN KEY (CourseID,schoolID) REFERENCES Course(id, SchoolID),
);
INSERT dbo.School ( id )
VALUES ( 1 ), ( 2 );
INSERT dbo.Student
( id, schoolID )
VALUES ( 19950516, 1 );
INSERT dbo.Course
( id, schoolID )
VALUES ( 77666, 1 ),
( 99988, 2 );
-- Student in same school as course is OK
INSERT dbo.StudentInCource
( StudentId, schoolId, CourseID )
VALUES ( 19950516, 1, 77666 );
-- Student in other school as course is FAIL
INSERT dbo.StudentInCourse
( StudentId, schoolId, CourseID )
VALUES ( 19950516, 2, 99988 );
INSERT dbo.StudentInCourse
( StudentId, schoolId, CourseID )
VALUES ( 19950516, 1, 99988 );
我建议制作:
三个字段 Pivot(StudentID,CourseID,SchoolID)
a Primary Key
这两个字段 Pivot(StudentID,SchoolID)
a double Foreign Key
to the Student
table
这两个字段 Pivot(CourseID,SchoolID)
a double Foreign Key
to the Course
table
所以模型会变成这样:
学校Table:
+----------+
| SchoolID |
+----------+
| 1 |
| 2 |
| 3 |
+----------+
其中 SchoolID
是 Primary Key
课程Table:
+----------+----------+
| CourseID | SchoolID |
+----------+----------+
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
+----------+----------+
其中 SchoolID
引用学校 (SchoolID)
和 (CourseID,SchoolID) a Primary Key
学生Table:
+-----------+----------+
| StudentID | SchoolID |
+-----------+----------+
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
+-----------+----------+
其中 SchoolID
引用学校 (SchoolID)
和 (StudentID ,SchoolID) a Primary Key
枢轴Table:
+-----------+----------+----------+
| StudentID | CourseID | SchoolID |
+-----------+----------+----------+
| 1 | 1 | 1 |
| 2 | 2 | 1 |
| 3 | 3 | 1 |
+-----------+----------+----------+
其中 Pivot
(StudentID,SchoolID) 引用 Student
(StudentID,SchoolID)
和Pivot
(CourseID,SchoolID)引用Course
(CourseID,SchoolID)
最好有 4 个 table,每个 School, Student, Course
和 table 用于将学生映射到特定课程。
单独映射学生课程 table 将使您能够映射单个学生与多个课程。
这是您可以做的最简单的事情。
如果您需要将同一个学生映射到不同的学校,那么您可以在相同的 table 或单独的 table
中添加映射学生和课程
这是我的数据库结构,它包含 3 tables : School, Student, Course
每个学生都必须属于一所学校(因此学校 ID 将是学生 table 中引用学校 table 的外键)。
每门课程还必须属于一所学校(因此学校 ID 将是课程 table 中指向学校 table 的外键)。
最后,每个学生可以注册一门或多门课程(pivot table 学生有一个外键,学校有一个外键),但有一个限制,即学生和课程都必须属于同一所学校。不允许学生报名参加与学生属于不同学校的课程。
有没有办法在枢轴 table 中添加此约束,或者以其他方式对其建模?
还是应该在每次插入主元之前在代码中强制执行约束 table?
您可以将 SchoolID 作为主键的一部分添加到学生和课程中。
这将强制那些 table 的外键也指定 SchoolID。
我们在 StudentInCourse-table 中使用这个事实来强制学生和课程都属于同一所学校。
CREATE TABLE School(id INT PRIMARY KEY);
CREATE TABLE Course(id int, schoolID INT
FOREIGN KEY REFERENCES dbo.School(id),
PRIMARY KEY(id, schoolID));
CREATE TABLE Student(id INT, schoolID INT
FOREIGN KEY REFERENCES dbo.School(id),
PRIMARY KEY(id, SchoolID));
CREATE TABLE StudentInCourse(StudentId INT, schoolId INT, CourseID INT,
CONSTRAINT [fk_student]
FOREIGN KEY (StudentId,schoolID) REFERENCES student(id, SchoolID),
CONSTRAINT [fk_course]
FOREIGN KEY (CourseID,schoolID) REFERENCES Course(id, SchoolID),
);
INSERT dbo.School ( id )
VALUES ( 1 ), ( 2 );
INSERT dbo.Student
( id, schoolID )
VALUES ( 19950516, 1 );
INSERT dbo.Course
( id, schoolID )
VALUES ( 77666, 1 ),
( 99988, 2 );
-- Student in same school as course is OK
INSERT dbo.StudentInCource
( StudentId, schoolId, CourseID )
VALUES ( 19950516, 1, 77666 );
-- Student in other school as course is FAIL
INSERT dbo.StudentInCourse
( StudentId, schoolId, CourseID )
VALUES ( 19950516, 2, 99988 );
INSERT dbo.StudentInCourse
( StudentId, schoolId, CourseID )
VALUES ( 19950516, 1, 99988 );
我建议制作:
(StudentID,CourseID,SchoolID)
a Primary Key
(StudentID,SchoolID)
a double Foreign Key
to the Student
table
(CourseID,SchoolID)
a double Foreign Key
to the Course
table
所以模型会变成这样:
学校Table:
+----------+
| SchoolID |
+----------+
| 1 |
| 2 |
| 3 |
+----------+
其中 SchoolID
是 Primary Key
课程Table:
+----------+----------+
| CourseID | SchoolID |
+----------+----------+
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
+----------+----------+
其中 SchoolID
引用学校 (SchoolID)
和 (CourseID,SchoolID) a Primary Key
学生Table:
+-----------+----------+
| StudentID | SchoolID |
+-----------+----------+
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
+-----------+----------+
其中 SchoolID
引用学校 (SchoolID)
和 (StudentID ,SchoolID) a Primary Key
枢轴Table:
+-----------+----------+----------+
| StudentID | CourseID | SchoolID |
+-----------+----------+----------+
| 1 | 1 | 1 |
| 2 | 2 | 1 |
| 3 | 3 | 1 |
+-----------+----------+----------+
其中 Pivot
(StudentID,SchoolID) 引用 Student
(StudentID,SchoolID)
和Pivot
(CourseID,SchoolID)引用Course
(CourseID,SchoolID)
最好有 4 个 table,每个 School, Student, Course
和 table 用于将学生映射到特定课程。
单独映射学生课程 table 将使您能够映射单个学生与多个课程。
这是您可以做的最简单的事情。
如果您需要将同一个学生映射到不同的学校,那么您可以在相同的 table 或单独的 table
中添加映射学生和课程