wake-up-neo.net

Kann der Fremdschlüssel null sein?

In unserem Datenbankprojekt haben wir eine Tabelle Sale, die einen Primärschlüssel und zwei exklusive Fremdschlüssel enthält: Vehicle_ID und Piece_ID. Wenn wir beispielsweise ein Fahrzeug verkaufen, benötigen wir Vehicle_ID als Fremdschlüssel, aber nicht Piece_ID. Können wir NULL auf Piece_ID setzen, könnte ein Fremdschlüssel null sein? Oder gibt es eine Möglichkeit, diesen Job zu erledigen?

Vielen Dank.

11
notfound90

Die Spalte (oder Spalten) eines Primärschlüssels muss NOT NULL sein. Ein Datensatz kann nicht eindeutig durch eine NULL identifiziert werden. Daher müssen die ID-Spalten am referenzierten Ende des Fremdschlüssels als NOT NULL definiert werden.

Es ist jedoch eine legitime Entwurfsentscheidung, dass eine Fremdschlüsselbeziehung optional ist, und die Art und Weise der Darstellung ist, das Referenzierungsende des Schlüssels optional zu machen, d. H. NULL zulassen.

In Bezug auf die Datenmodellierung haben Sie einen (exklusiven) Bogen beschrieben: "eine Tabelle mit zwei oder mehr Fremdschlüsseln, bei denen einer und nur einer von ihnen nicht null sein kann". In der logischen Modellierung sind Bögen durchaus akzeptabel, aber es gibt eine starke Meinung für die Implementierung als separate Tabellen. In Ihrem Szenario wäre dies eine generische Sale-Tabelle plus zwei Untertypen-Tabellen, VehicleSale und PieceSale.

Die Vorteile der separaten Tabellenimplementierung sind:

  • die Fremdschlüsseleinschränkungen leichter durchzusetzen;
  • es ist einfacher, zusätzliche Spalten hinzuzufügen, die sich beispielsweise auf Fahrzeugverkäufe beziehen, die nicht für Stückverkäufe gelten.
  • einfacher, das Modell um zusätzliche Untertypen zu erweitern;
  • klareres Datenmodell, das die Anwendungsentwicklung vereinfachen kann.

Die Vorteile sind jedoch nicht alle einseitig. Es ist zwar ziemlich einfach sicherzustellen, dass eine Sale entweder für eine VehicleSale oder für eine PieceSale gilt, jedoch nicht für beides, aber das Erzwingen einer Regel, dass eine Sale muss einen untergeordneten Datensatz haben, wird in der Regel ziemlich unwichtig.

Der vorherrschende Rat lautet also, dass ein ausschließlicher Bogen falsch ist, und es ist im Allgemeinen ein guter Rat. Aber es ist nicht so klar wie manche ausmachen.

11
APC

Antworten:

Ja, Sie können das tun - machen Sie die FKs NULL-fähig, fügen Sie jedoch einen CHECK hinzu, um sicherzustellen, dass genau einer von ihnen einen Nicht-NULL-Wert enthält.

Ausarbeitung:

Ein FK kann NULL-fähig sein, wodurch eine 1..0: N-Beziehung modelliert wird. Mit anderen Worten, eine "untergeordnete" Zeile kann (muss aber nicht) eine "übergeordnete" Zeile haben.

Ein NOT NULL-Fremdschlüssel modelliert eine 1: N-Beziehung. Mit anderen Worten, jedes Kind muss ein Elternteil haben.

Wenn ein FK zusammengesetzt ist1und mindestens eines der Felder ist NULL-fähig, eine Mischung aus NULL- und Nicht-NULL-Werten wird auf besondere Weise behandelt:

  • Wenn der FK MATCH FULL ist, müssen entweder all - Werte NULL sein oder alle Werte müssen nicht NULL sein und mit einer übergeordneten Zeile übereinstimmen.
  • Wenn der FK MATCH PARTIAL ist, müssen nur die Werte, die nicht NULL sind, mit einer übergeordneten Zeile übereinstimmen (NULL-Werte werden ignoriert).
  • Wenn das FK MATCH SIMPLE ist, sind entweder alle Werte nicht NULL und müssen mit einer übergeordneten Zeile übereinstimmen, oder es gibt mindestens einen NULL-Wert (in diesem Fall müssen die NULL nicht übereinstimmen).

Die meisten DBMSes setzen standardmäßig auf MATCH SIMPLE (mit der bemerkenswerten Ausnahme von MS Access ) und die meisten unterstützen nichts anderes als die Standardeinstellung.


1 Was Sie hier nicht haben - erwähnen Sie es einfach der Vollständigkeit halber.

6

Abhängig davon, was Sie unter "exklusiven Fremdschlüsseln" verstehen, denken Sie möglicherweise an Fahrzeuge und Teile als zwei Unterklassen einer größeren Superklasse, die als verkaufsfähige Artikel bezeichnet wird. 

Wenn Sie ein Entwurfsmuster mit der Bezeichnung "Vererbung der Klassentabellen" verwenden, haben Sie drei Tabellen, eine für die Oberklasse und eine für jede Unterklassentabelle. Wenn Sie außerdem ein Design verwenden, das als "gemeinsam genutzter Primärschlüssel" bezeichnet wird, können Sie für alle drei Tabellen denselben Primärschlüssel verwenden.

Dies würde es Ihrer Verkaufstabelle ermöglichen, einen einzelnen Fremdschlüssel, Saleable_Item_Id, zu haben, der je nach Fall auf die Tabelle Saleable_Item und auch auf die Tabelle Vehicle oder Piece verweist. Dies könnte für Sie besser ausfallen als das vorhandene Design.

google "Vererbung von Klassentabellen" und "gemeinsam genutzter Primärschlüssel" für weitere Details.

1
Walter Mitty

Oracle sollte sich nicht beschweren, wenn Sie einen ungültigen Fremdschlüssel haben.

Waren Sie auf einige Fehler gestoßen?

0
Andrew Walters