it-swarm.com.de

Nachteile der Verwendung eines nullbaren Fremdschlüssels anstelle der Erstellung einer Schnittpunkttabelle

Angenommen, ich habe das folgende ER-Diagramm:

(enter image description here

Wenn ich nun die Beziehung mit einem Fremdschlüssel von School in Student darstellen würde, könnte ich NULL Werte haben (da ein Student nicht dazu gehören muss a School), zum Beispiel:

(enter image description here

Der richtige Weg (basierend auf dem, was ich gelesen habe) besteht darin, eine Schnittpunkttabelle zu erstellen, um die Beziehung darzustellen, zum Beispiel:

(enter image description here

Auf diese Weise können in der Tabelle School_has_Student Keine NULL -Werte vorhanden sein.

Aber was sind die Nachteile der Verwendung eines nullbaren Fremdschlüssels anstelle der Erstellung einer Schnittpunkttabelle?


Bearbeiten:

Ich habe fälschlicherweise (school_id, student_id) Als Primärschlüssel für die Tabelle School_has_Student Ausgewählt, wodurch die Beziehung viele zu viele wurde. Der richtige Primärschlüssel sollte student_id Sein:

(enter image description here

16
Tom

Die beiden Modelle repräsentieren unterschiedliche Beziehungen.

Mithilfe einer Verknüpfungstabelle modellieren Sie eine Viele-zu-Viele-Beziehung.

Mit einem einfachen Fremdschlüssel modellieren Sie eine Eins-zu-Viele-Beziehung.

Der Nachteil eines nullbaren Fremdschlüssels besteht darin, dass die Beziehung nicht als viele-zu-viele-Beziehungen modelliert werden kann, wenn Sie dies erreichen möchten.


Basierend auf Ihrer Bearbeitung der Frage teilen Sie die Schülertabelle effektiv in zwei Tabellen mit demselben Schlüssel auf. Ich sehe dies im Allgemeinen auf Tischen mit viel zu vielen Feldern, sodass jemand sie in zwei Teile aufteilt, um sie besser handhaben zu können (ich nenne es Lippenstift auf ein Schwein setzen).

Durch Aufteilen der Schülertabelle machen Sie die zweite Tabelle optional, da in der zweiten Tabelle kein Datensatz vorhanden sein muss. Das ist einem Feld sehr ähnlich, das nicht gesetzt werden muss, weil es null sein kann.

Wenn Sie eine Eins-zu-Viele-Beziehung wünschen, ist es weitaus besser, eine einzelne Tabelle zu verwenden und zuzulassen, dass die Schul-ID in der Schülertabelle null ist. Es gibt keinen Grund, Nullen in Feldern zu vermeiden, selbst für einen Fremdschlüssel. Dies bedeutet, dass die Fremdbeziehung optional ist: Entwickler und Datenbankadministratoren verstehen dies eindeutig, und das zugrunde liegende Datenbankmodul sollte auf jeden Fall einwandfrei funktionieren.

Machen Sie sich keine Sorgen, wenn Sie sich Gedanken über Joins machen. Es gibt genau definierte Semantiken für die Funktionsweise von Joins mit Nullfeldern. Wenn Sie eine einzelne Tabelle verwenden, können Sie zwei statt drei Tabellen verbinden.

19
user22815

Sie haben in einem Kommentar oben geschrieben:

das Buch "Grundlagen von Datenbanksystemen" [...] besagt, dass [...] empfohlen wird, eine Schnittpunkttabelle zu verwenden, wenn die Fremdschlüsselspalte viele NULL-Werte enthält (z. B. wenn 98% der Mitarbeiter keine Abteilung leiten)

Wenn die Fremdschlüsselspalte viele NULL-Werte enthält, müssen Ihre Programme diese meist leere Spalte für jeden Datensatz verarbeiten, den sie verarbeiten. Die Spalte wird wahrscheinlich etwas Speicherplatz belegen, obwohl sie in 98% aller Fälle leer ist. Wenn Sie die Beziehung abfragen, müssen Sie die Spalte abfragen, die Ihnen mehr Netzwerkverkehr bietet. Wenn Sie ein ORM verwenden, das Ihre Klassen aus Ihren Tabellen generiert, Ihre Programme benötigt auch mehr Platz auf der Client-Seite als nötig. Die Verwendung einer Schnittstellentabelle vermeidet dies. Es sind nur Verknüpfungsdatensätze erforderlich, bei denen der entsprechende Fremdschlüssel sonst nicht NULL wäre.

Im Gegensatz dazu, wenn Sie nicht nur ein paar NULL-Werte haben, sagen wir, dass 50% oder mehr Beziehungen nicht NULL sind, ergibt die Verwendung einer Schnittpunkttabelle den gegenteiligen Effekt: mehr Speicherplatz, höhere Komplexität, was zu mehr Netzwerkverkehr usw. führt.

Die Verwendung einer Schnittpunkttabelle ist also nur eine Form der Optimierung, die nur für einen bestimmten Fall sinnvoll ist, und insbesondere heutzutage, wo Speicherplatz und Speicher billiger wurden und viel seltener benötigt werden. Beachten Sie, dass "Fundamentals of Database Systems" ursprünglich vor mehr als 20 Jahren geschrieben wurde (ich fand einen Verweis auf die zweite Ausgabe von 1994), und ich denke, dass die Empfehlung zu diesem Zeitpunkt bereits vorhanden war. Vor 1994 war die Speicherplatzoptimierung wahrscheinlich viel wichtiger als heute, da Massenspeicher immer noch teurer waren und Computer und Netzwerke viel langsamer als heute.

Als Randnotiz zu einem wählerischen Kommentar: Die obige Aussage versucht nur zu antizipieren, was der Autor von "Fundamentals of Database Systems" mit seiner Empfehlung im Sinn hatte. Ich denke, er hat eine grobe, allgemeine Aussage gemacht, die gültig ist Für die meisten Systeme. In einigen Datenbanken gibt es andere mögliche Optimierungen wie "spärliche Spalten", die die Verwendung einer Schnittpunkttabelle noch veralteter machen.

Verstehen Sie diese Empfehlung also nicht falsch. Das Buch sagt Ihnen nicht, dass Sie Schnittpunkttabellen für {0,1}:n - Beziehungen im Allgemeinen bevorzugen oder - wie Sie geschrieben haben - dass dies der "richtige Weg" ist. Verwenden Sie solche Optimierungen, die Ihre Programme nur dann komplizierter machen, wenn Sie sie wirklich benötigen.

7
Doc Brown

Das konzeptionelle Modell wird so aussehen, was sehr unorthodox ist, um es weniger auszudrücken:

(enter image description here

Das physikalische Modell wird so aussehen, was verwirrend ist, um es weniger auszudrücken (die Leute werden denken, es ist M: M, wenn sie nicht genau hinsehen):

(enter image description here

Mein Vorschlag:

Wenn Sie viele Spalten (FK oder andere) haben, die für die meisten Schüler nicht gelten, trennen Sie die Tabellen in Rollentabellen mit 1: 1-Rel. Dies liegt jedoch nicht daran, dass es sich um FK handelt, sondern daran, dass die Spalten für die meisten Zeilen nicht gelten.

Andernfalls , nullable FK sind ein normaler Teil einer Datenbank und Join-Tabellen sind normalerweise für M: M rels.

Häufige Verwendungen von 1: 1-Rels sind für Rollentabellen mit Spalten, die nur gelten, wenn die Entität von einem bestimmten Typ ist, und das Extrahieren von BLOB-Spalten für die Leistung oder Überlegungen zur Speicherung. Das Avodieren von Nullwerten in FKs ist dafür keine übliche Verwendung.

(enter image description here

2

Neben anderen Antworten möchte ich darauf hinweisen, dass ein Nullwert für den Fremdschlüssel nicht eindeutig ist. Bedeutet es:

1) Die Schule des Schülers (falls vorhanden) ist unbekannt (dies ist die Standardbedeutung von 'null' - Wert ist unbekannt)

2) Es ist bekannt, ob der Schüler eine Schule hat oder nicht, und sie haben keine

Wenn Sie die Standardbedeutung von null verwenden, wie würden Sie "Schüler hat keine Schule" in Ihrem Fremdschlüsselmodell darstellen? In diesem Fall müssten Sie wahrscheinlich einen Eintrag "Keine Schule" mit einer eigenen ID in der Schultabelle erstellen. (Nicht ideal)

2
Brad Thomas

Datenbanktabellen haben dieses nette Ding, das man Einschränkungen nennt. Es ist also sehr einfach, eine Kreuzungstabelle zu erstellen, in der nur einer von jedem Schüler in der Tabelle angezeigt wird, aber viele Schulen in dieser Tabelle. Effektiv geben Sie eine

Theorie ist schön, aber am Ende werden Sie Ihre Datenbank nach den Fragen modellieren, die Sie stellen.

Wenn Sie häufig mit der Frage "Welche Schüler sind in meiner Schule?" Fragen möchten, möchten Sie wirklich die gesamte Schülertabelle abfragen oder eine einfache Schnittpunkttabelle haben.

In Datenbanken: Optimieren Sie für die Fragen, die Sie stellen.

1
Pieter B

Es gibt einen Anwendungsfall, in dem die Verwendung einer dritten Tabelle tatsächlich sinnvoll sein kann. Das Beispiel mag rein hypothetisch erscheinen, aber ich hoffe, es veranschaulicht meinen Standpunkt gut. Nehmen wir an, Sie fügen der Tabelle students weitere Spalten hinzu und entscheiden sich irgendwann dafür, die Eindeutigkeit der Datensätze über einen zusammengesetzten Index für mehrere Spalten zu erzwingen. Es ist sehr wahrscheinlich, dass Sie das school_id Spalte auch, und hier beginnen die Dinge chaotisch zu werden. Aufgrund der Art und Weise, wie SQL entworfen wurde, wurden mehrere identische Datensätze eingefügt, wobei school_id is NULL wird möglich sein. Aus technischer Sicht ist dies durchaus sinnvoll, jedoch nicht intuitiv und kann zu unerwarteten Ergebnissen führen. Auf der anderen Seite ist es einfach, die Eindeutigkeit der Kreuzungstabelle zu erzwingen.

Ich musste kürzlich eine solche "optionale" Beziehung modellieren, bei der die Anforderung einer Eindeutigkeitsbeschränkung auf eine Zeitstempelspalte zurückzuführen war. Wenn Sie den nullbaren Fremdschlüssel in der Tabelle belassen, können Sie plötzlich Datensätze mit demselben Zeitstempel einfügen (nehmen wir an, es handelt sich um einen Standardschlüssel, der für Datensätze festgelegt wurde, die noch nicht geprüft/genehmigt wurden) - und der einzige Ausweg war das Entfernen nullfähige Spalte.

Wie Sie sehen können, handelt es sich um einen ziemlich spezifischen Fall, und wie andere angemerkt haben, sind Sie in den meisten Fällen mit allen NULL -Werten vollkommen in Ordnung. Es hängt wirklich von den spezifischen Anforderungen Ihres Modells ab.

0
petkov.np

Zusätzlich zu den vielen guten Vorschlägen, die bereits eingereicht wurden, bin ich persönlich kein Fan von Fremdschlüsseln, es sei denn, sie sind wirklich notwendig. Zuerst gibt es die M: M-Beziehung, auf die Sie verweisen. Das Aufrufen eines Fremdschlüssels und damit das Abrufen dieser Tabellendaten in Ihre Abfragen führt zu einer höheren Komplexität und je nach Tabellengröße zu einer langsameren Leistung. Wie andere bereits gesagt haben, können nullfähige FK-Felder nicht unterstützt werden und Datenintegritätsprobleme verursachen.

Wenn Sie einen Zustand definieren, in dem die Schülerschule unbekannt oder leer ist, unterscheidet NULL diese Bedingungen nicht. (Wir kehren wieder zur Datenintegrität zurück.) Der Vorschlag für eine Rollentabelle von Tulains ist elegant und lässt Nullwerte sauber zu.

0
Aby Sheffer