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     |
    +----------+
    

    其中 SchoolIDPrimary 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

    中添加映射学生和课程