SQL: Fremdschlüssel, der ein Kind eines anderen Fremdschlüssels ist

Ich möchte nach einem bestimmten Problem fragen, das ich habe.

Zum Beispiel habe ich eine Student Tabelle mit einer SchoolID und einer ClassID , die beide Fremdschlüssel für die School bzw. die Classroom Tabelle sind. Die Class Tabelle hat eine SchoolID Spalte, die ein Fremdschlüssel für die School Tabelle ist.

Kann ich irgendwie sicherstellen, dass die ClassID in der Student Tabelle ein Kind der SchoolID , oder muss ich die SchoolID entfernen und nur mit der ClassID leben, um mögliche Diskrepanzen zu vermeiden?

Ja, technisch sollten Sie den Student.SchoolId entfernen, wenn Class bereits SchoolId , da dies bereits die Beziehung zwischen Student und School .

Abgesehen davon gibt es einige allgemeine "exceptionn", z.

  1. Wenn die Beziehung zwischen Student und School etwas anderes bedeuten kann als die Beziehung zwischen Class und School (z. B. wenn der Schüler zur Schule X als "seine / ihre Hauptschule" geht, aber dann auch an einer zusätzlichen class Y in der Schule Z teilnimmt). (Tatsächlich könnte dies einen modelierungserrors hervorheben, dh Student: Class könnte tatsächlich eine Viele-zu-Viele-Beziehung sein)

  2. Aus performancesgründen ist es manchmal (eine etwas widerwillige) Wahl, den Fremdschlüssel des Elterns zu einem Kind hinzuzufügen, um die Notwendigkeit zu vermeiden, sich dem Elternteil anzuschließen. Aber wie Sie sagen, kann dies zu Integritätsproblemen führen.

Ja, Sie können dies erzwingen, indem Sie mehrere Spalten in Ihrem Fremdschlüssel auf die Tabelle " Classes verweisen:

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

Je nach Geschmack können Sie entscheiden, einen Fremdschlüssel nur in der Spalte " ClassID in beiden Tabellen zu deklarieren.

Die Student-Tabelle sollte auf class verweisen.

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

Die Class-Tabelle sollte wiederum auf School verweisen.