it-swarm.com.de

Warum benötigen zusammengesetzte Fremdschlüssel eine separate eindeutige Einschränkung?

Hier ist eine einfache Tabelle, in der Datensätze auf übergeordnete Datensätze in derselben Tabelle verweisen können:

CREATE TABLE foo (
    id         SERIAL  PRIMARY KEY,
    parent_id  INT     NULL,
    num        INT     NOT NULL,
    txt        TEXT    NULL,
    FOREIGN KEY (parent_id) REFERENCES foo(id)
);

Mit der zusätzlichen Anforderung, dass einer der anderen Feldwerte (num) zwischen übergeordneten und untergeordneten Datensätzen identisch sein muss, dachte ich, dass ein zusammengesetzter Fremdschlüssel den Trick machen sollte. Ich habe die letzte Zeile in geändert

    FOREIGN KEY (parent_id, num) REFERENCES foo(id, num)

und got FEHLER: Es gibt keine eindeutige Einschränkung für die angegebenen Schlüssel für die referenzierte Tabelle "foo".

Ich kann diese Einschränkung leicht hinzufügen, verstehe aber nicht, warum dies erforderlich ist, wenn eine der referenzierten Spalten (id) bereits eindeutig ist. So wie ich es sehe, wäre die neue Einschränkung überflüssig.

10
Zilk

Es ist eine Einschränkung des DBMS - soweit ich weiß in allen. Und das nicht nur beim Hinzufügen einer Spalte, sondern auch beim Neuanordnen von Spalten. Wenn wir eine UNIQUE -Einschränkung für (a1, a2) Haben, können wir keine FOREIGN KEY Hinzufügen, die REFERENCES (a2, a1), es sei denn, es gibt eine eindeutige Einschränkung für diese (a2, a1) Das ist im Wesentlichen redundant.

Es wäre nicht besonders schwierig, dies als Feature hinzuzufügen:

Wenn es eine UNIQUE -Einschränkung für (a) Gibt, ist auch jede (a, b, c, ..., z) Oder (b,c, ...a, ...z) Kombination garantiert UNIQUE.

oder die Verallgemeinerung:

Wenn für (a1, a2, ..., aN) Eine UNIQUE -Einschränkung besteht, ist auch jede (a1, a2, ..., aN, b1, b2, ..., bM) - Kombination oder Neuanordnung UNIQUE garantiert.

Es scheint, dass es nicht gefragt wurde oder nicht als hoch genug eingestuft wurde, um implementiert zu werden.

Sie können jederzeit - im jeweiligen Kanal - eine Anfrage für die zu implementierende Funktion stellen. Oder implementieren Sie es sogar selbst, wenn das DBMS Open Source ist, wie Postgres.

11
ypercubeᵀᴹ

Fremdschlüssel im Allgemeinen (nicht nur zusammengesetzt) ​​MÜSSEN auf einen EINZIGARTIGEN SCHLÜSSEL in einer anderen Tabelle verweisen. Andernfalls würde es keine relationale Datenintegrität geben.

Dies ist eine Beschwerde, weil Sie zwar einen eindeutigen Schlüssel für (id) haben, aber keinen eindeutigen Schlüssel für (id, num). Für die Datenbank ist das Paar (id, num) also nicht GARANTIERT, einzigartig zu sein. Wir Menschen können herausfinden, dass es einzigartig sein wird, aber ich bin sicher, dass es eine Menge zusätzlichen Code geben würde, den sie hinzufügen müssten, um Postgres klug genug zu machen, um zu sehen, dass "oh hey ... id soll einzigartig sein." , also id, num sollte auch eindeutig sein "..

Ich wäre sehr überrascht, wenn sie diesen Code hinzufügen würden, wenn Sie lediglich einen weiteren eindeutigen Index für die beiden Spalten erstellen müssten, um das Problem zu beheben.

Um ganz klar zu sein, der Code, den sie hinzufügen müssten, wäre nicht nur dieser einfache Fall ... er müsste alle Fälle behandeln, auch solche, bei denen sich der Fremdschlüssel in mehr als 4 Spalten befindet usw. Ich bin sicher Die Logik wäre ziemlich komplex.

5
Joishi Bodio