Warum sollte ich nicht eine Tabelle für mehrere Beziehungen haben?

12

Angenommen, ich habe mehrere Beziehungen in meiner Datenbank, z. B. Geschäft, Mitarbeiter und Verkauf, und ich möchte Paare mit einer einfachen binären Beziehung verbinden. Persönlich würde ich Tabellen mit den Namen Employee_Store und Employee_Sale mit einem natürlichen Schlüssel erstellen, der aus den Fremdschlüsseln besteht.

Jetzt besteht mein Kollege darauf, eine Tabelle für mehrere Beziehungen zu erstellen. Für das obige Beispiel könnte es eine Tabelle mit dem Namen EmployeeLinks geben:

EmployeeLinks(
    IdLink int PK, 
    IdEmployee int FK null,
    IdStore int FK null,
    IdSale int FK null,
    LinkType int not null
)

Bitte helfen Sie mir mit guten Gründen, warum dies keine gute Idee ist. Ich habe meine eigenen Argumente, aber ich möchte sie privat halten und Ihre unvoreingenommenen Meinungen hören.

BEARBEITEN:

Anfangs hätte die obige Tabelle keinen Primärschlüssel (!). Da die Fremdschlüssel null zulassen, ist ein Ersatzschlüssel die einzige Option.

Tomasz Pluskiewicz
quelle
3
Es ist wie OTLT oder EAV, aber schlimmer, weil es eher Spalten als Zeilen vermehrt!
Tag, wenn

Antworten:

13

Was schlägt Ihr Kollege als Primärschlüssel für diese Verknüpfungstabelle vor?
Primärschlüsselspalten dürfen natürlich nicht NULL sein: Die obige Tabelle ist nullbar.

Im obigen Beispiel gibt es keine natürliche Zeilenkennung (was eine PK ist) (eine IDENTITY-Spalte ist kein Primärschlüssel), daher schlägt sie in keinem Modellierungsprozess fehl . Denken Sie nicht einmal daran, Tabellen ohne Modell zu erstellen (ERD, ORM, IDEF1X, was auch immer).

Sie benötigen außerdem CHECK-Einschränkungen, um sicherzustellen, dass Sie keine 3-Wege-Links haben.

Schließlich verirren Sie sich in das Gebiet der 4. und 5. Normalform, aber aus den falschen Gründen.

Ich kann im Internet keine Beispiele finden: Das zeigt, wie dumm das ist

gbn
quelle
4
+1 fürI can't find any examples on the internet: that shows how stupid this is
JNK
Ich habe den Primärschlüssel klarer gemacht. Außerdem ist mein Kollege anscheinend schon einmal auf ein solches Design
gestoßen,
@Tomasz Pluskiewicz: Ein Ersatzschlüssel ist nicht der Primärschlüssel! Es wird ausgewählt, um den natürlichen Schlüssel zum Zeitpunkt der Implementierung zu ergänzen. Siehe dba.stackexchange.com/a/13779/630. Außerdem sollte Ihr Kollege uns einen maßgeblichen Artikel zeigen, der diese Technik demonstriert. Ich habe in meiner Zeit ganze Müllberge gesehen, aber ich wiederhole sie nicht ...
gbn
12

Der erste praktische Grund, an den ich denken kann, ist die Leistung.

In einem "traditionellen" Modell können Sie einen eindeutigen Index für Idemployee, Idstoreoder unabhängig von den Feldern haben und bei Suchvorgängen eine hervorragende Leistung erzielen. Es ist auch für Einsätze leicht zu pflegen. Mit einzigartigen Indizes können Sie JOINVerknüpfungen häufiger zusammenführen, was sehr schnell gehen kann.

In Ihrem Beispielmodell müssen Sie für jedes FK-Feld in der Tabelle mindestens einen einzelnen Feldindex für jedes FK-Feld in der Tabelle haben, idealerweise einen Abdeckungsindex für alle Kombinationen, auf die verwiesen wird, dh:

  • Mitarbeiter / Geschäft
  • Mitarbeiter / Verkauf

Ich bin nicht sicher, was Linktyp ist, aber wenn Sie darauf verweisen, sollte es wahrscheinlich indiziert werden.

Diese Indizes müssen für jede Zeile in der Tabelle verwaltet werden, unabhängig davon, ob das Feld ausgefüllt ist oder nicht. Sie können einen Filter hinzufügen, aber das wird bei so vielen Kombinationen auch schwierig.

Es wird auch Ihre Logik komplizieren. Sie müssen entweder die Mitarbeiter-ID nachschlagen, eine Zeile mit einem leeren Speicherwert suchen und aktualisieren. Oder fügen Sie einfach eine neue Zeile für jeden neuen Link ein, wodurch der Zweck der Konsolidierung der Felder zunichte gemacht wird.

Grundsätzlich verwenden Sie MEHR Speicherplatz, müssen MEHR Indizes verwalten und komplizieren Ihre Logik im Wesentlichen ohne Grund. Der einzige "Vorteil" ist, dass weniger Tabellen behandelt werden müssen.

JNK
quelle
Die LinkType-Spalte ist so etwas wie ein Diskriminator. Ich sage nur, auf welches Paar sich eine Reihe tatsächlich bezieht. Fügt nur zur Erfindung hinzu, wenn Sie mich fragen.
Tomasz Pluskiewicz
@TomaszPluskiewicz Ich denke, der beste Weg, ihm zu zeigen, warum es scheiße ist, besteht darin, ein Beispieldatensatz mit beiden Arten von Tabellen zu erstellen und einige Abfragen auszuführen. Sein Modell wird viel langsamer sein als ein traditionelles Modell
JNK
4

Das Einfügen mehrerer Beziehungen in eine Tabelle kann hilfreich sein, wenn diese Beziehungen dieselben Attribute haben und / oder wenn Sie Daten über mehrere Beziehungen hinweg aggregieren möchten.

Dies ist erforderlich, wenn die Beziehungstypen zur Laufzeit vom Benutzer definiert werden. Dies ist jedoch selten wirklich der Fall.

In Ihrem Beispiel teilen die Beziehungen keine Attribute, die Beziehungen verweisen sogar auf zwei verschiedene Tabellen. Dies macht es schwierig, Einschränkungen durchzusetzen, und das Design ist auch weniger intuitiv.

Ich würde dieses Design nur wählen, wenn das Erstellen von Tabellen buchstäblich Geld kostet.

JMD Coalesce
quelle