Warum sollte eine Tabelle ihren Primärschlüssel als Fremdschlüssel für sich selbst verwenden?

21

Beim Durchsuchen einer Datenbank stieß ich auf eine Tabelle, die ihren Primärschlüssel als Fremdschlüssel für sich selbst verwendete.

Ich habe gesehen, dass eine Tabelle einen Fremdschlüssel für sich selbst haben kann, um eine Hierarchiestruktur zu erstellen, aber eine andere Spalte verwenden würde, um auf den Primärschlüssel zu verweisen.

Da der Primärschlüssel eindeutig ist, kann die Zeile in dieser Situation nicht nur auf sich selbst verweisen. Das scheint eine tautologische Verbindung zu sein, denn wenn ich schon die Reihe habe, dann habe ich schon die Reihe.

Gibt es einen Grund dafür?

Der Tisch ist mit sich selbst verbunden

Ich bin sicher, dass die Einschränkung so geschrieben ist (nicht nur im Diagramm), da für beide Hälften der Definition dieselbe Tabelle und Spalte verwendet wird.

Aaroninus
quelle
6
Wahrscheinlich durch reißerischen Gebrauch des Designers ist meine Theorie
Martin Smith

Antworten:

27

Wie du gesagt hast. Eine FOREIGN KEYEinschränkung, die auf dieselbe Tabelle verweist, gilt normalerweise für eine Hierarchiestruktur und verwendet eine andere Spalte, um auf den Primärschlüssel zu verweisen. Ein gutes Beispiel ist eine Tabelle mit Mitarbeitern:

EmployeeId    Int     Primary Key
EmployeeName  String
ManagerId     Int     Foreign key going back to the EmployeeId

In diesem Fall gibt es also einen Fremdschlüssel von der Tabelle zurück in sich. Alle Manager sind auch Angestellte, also ManagerIdist das eigentlich das EmployeeIddes Managers.

Wenn Sie andererseits meinen, dass jemand den EmployeeIdals Fremdschlüssel für die Employee-Tabelle verwendet hat , war dies wahrscheinlich ein Fehler . Ich habe einen Test durchgeführt und es ist möglich, aber es hätte keinen wirklichen Nutzen.

CREATE TABLE Employee (EmployeeId Int PRIMARY KEY,
                        EmployeeName varchar(50),
                        ManagerId Int);


ALTER TABLE Employee ADD CONSTRAINT fk_employee 
    FOREIGN KEY (EmployeeId) REFERENCES Employee(EmployeeId);
Kenneth Fisher
quelle
1
In diesem Fall kann es von Vorteil sein, die ManagerId in Bezug auf die EmployeeId einzuschränken, wenn die Manager "getrennt" werden. Auf diese Weise kann die Zeile nicht gelöscht werden. Ich würde es nicht so machen, aber es könnte von Vorteil sein, wenn sich Ihre Bewerbung auf Mitarbeiter stützt, die Manager haben.
zgr024
6

Ich habe gerade einen solchen Fremdschlüssel in meiner eigenen Datenbank gefunden und es muss ich selbst gemacht haben. Ich denke, das ist zufällig passiert. Wenn ich im Kontextmenü einer Tabelle mit Primärschlüssel (in Management Studio, SQL 2014 Express) auf "Neuer Fremdschlüssel" klicke, wird automatisch ein solcher Fremdschlüssel erstellt, der auf sich selbst verweist. Siehe unten:

Bildbeschreibung hier eingeben

Wenn ich dann nicht merke, dass ich dieses ändern sollte, anstatt ein neues hinzuzufügen, bleibt es dort. Oder wenn ich einfach auf die Schaltfläche [Schließen] klicke, was bedeutet, dass dies wie ein [Abbrechen] wäre, wird der Fremdschlüssel nach dem Speichern der Tabellendefinition immer noch erstellt.

Ein solcher Fremdschlüssel macht für mich also keinen Sinn und kann entfernt werden.

Stefan Müller
quelle
Es ist möglich, dass Sie eine FK erstellen wollten und dabei feststellen, dass die andere Tabelle ihre PK noch nicht festgelegt hat. Sie brechen also ab, gehen zur anderen Tabelle und vergessen aus irgendeinem Grund, den FK-Prozess fortzusetzen. Dort haben Sie Ihre rekursive FK.
Andrew
4

Vielleicht wollte der Designer die Verwendung von deaktivieren TRUNCATE TABLE?

TRUNCATE TABLEkann nicht für eine Tabelle mit einer Fremdschlüsseleinschränkung für eine andere Tabelle verwendet werden , kann jedoch verwendet werden, wenn selbstreferenzielle Fremdschlüssel vorhanden sind. Aus der Dokumentation zu TRUNCATE TABLE (Transact-SQL) :

BOL-Extrakt

Eine DELETEAnweisung ohne WHEREKlausel hat eine ähnliche Wirkung wie a TRUNCATE TABLE(alle Zeilen in der Tabelle entfernen), aber die DELETEAnweisung löst Löschauslöser aus, was möglicherweise ein Grund ist, dies zuzulassen, DELETEaber nicht TRUNCATE TABLE.

Ich würde dies mit Berechtigungen tun ( DELETELöschberechtigung erforderlich, Berechtigung zum TRUNCATE TABLEÄndern der Tabelle erforderlich), aber vielleicht gibt es einen Grund, warum der Designer dies nicht tun konnte?

Hinweis: Auch wenn das, was der Designer getan hat, die Verwendung von nicht deaktiviert TRUNCATE TABLE, spekuliere ich immer noch, dass dies ihre Absicht war.

Greenstone Walker
quelle