Kurze Version
Ich muss jedem Paar in einem bestehenden Many-to-Many-Join eine feste Anzahl zusätzlicher Eigenschaften hinzufügen. Wenn Sie zu den folgenden Diagrammen übergehen, welche der Optionen 1 bis 4 ist in Bezug auf Vor- und Nachteile die beste Möglichkeit, dies durch Erweiterung des Basisgehäuses zu erreichen? Oder gibt es eine bessere Alternative, die ich hier nicht in Betracht gezogen habe?
Längere Version
Derzeit habe ich zwei Tabellen in einer Viele-zu-Viele-Beziehung über eine Zwischen-Verknüpfungstabelle. Ich muss jetzt zusätzliche Links zu Eigenschaften hinzufügen, die zu dem Paar vorhandener Objekte gehören. Ich habe eine feste Anzahl dieser Eigenschaften für jedes Paar, obwohl ein Eintrag in der Eigenschaftentabelle für mehrere Paare gelten kann (oder sogar mehrfach für ein Paar verwendet werden kann). Ich versuche, den besten Weg zu finden, um dies zu erreichen, und habe Probleme, die Situation einzuschätzen. Semantisch scheint es so, als ob ich es genauso gut wie eines der folgenden beschreiben kann:
- Ein Paar, das mit einem Satz einer festen Anzahl zusätzlicher Eigenschaften verknüpft ist
- Ein Paar verbunden mit vielen zusätzlichen Eigenschaften
- Viele (zwei) Objekte, die mit einer Gruppe von Eigenschaften verknüpft sind
- Viele Objekte, die mit vielen Eigenschaften verknüpft sind
Beispiel
Ich habe zwei Objekttypen, X und Y, jeweils mit eindeutigen IDs, und eine Verknüpfungstabelle objx_objy
mit Spalten x_id
und y_id
, die zusammen den Primärschlüssel für die Verknüpfung bilden. Jedes X kann mit vielen Ys verknüpft sein und umgekehrt. Dies ist das Setup für meine bestehende Many-to-Many-Beziehung.
Base Case
Zusätzlich habe ich eine Reihe von Eigenschaften in einer anderen Tabelle definiert und eine Reihe von Bedingungen, unter denen ein gegebenes (X, Y) Paar die Eigenschaft P haben soll. Die Anzahl der Bedingungen ist fest und für alle Paare gleich. Sie sagen im Grunde "In Situation C1 hat das Paar (X1, Y1) die Eigenschaft P1", "In Situation C2 hat das Paar (X1, Y1) die Eigenschaft P2" und so weiter für drei Situationen / Bedingungen für jedes Paar im Join Tabelle.
Option 1
In meiner aktuellen Situation gibt es genau drei solche Bedingungen, und ich habe keinen Grund zu erwarten, zu erhöhen , um eine Möglichkeit , Spalten hinzuzufügen ist c1_p_id
, c2_p_id
und c3_p_id
zu der featx_featy
Angabe , für ein gegebenen x_id
und y_id
, das Eigentum p_id
an dem Einsatz in jedem der drei Fälle .
Dies scheint mir keine gute Idee zu sein, da dies die Auswahl aller auf ein Feature angewendeten Eigenschaften in SQL erschwert und eine Skalierung auf weitere Bedingungen nicht ohne Weiteres möglich macht. Es wird jedoch die Anforderung einer bestimmten Anzahl von Bedingungen pro (X, Y) Paar durchgesetzt. Tatsächlich ist dies die einzige Option, die dies tut.
Option 2
Erstellen Sie eine Bedingungstabelle cond
und fügen Sie die Bedingungs-ID zum Primärschlüssel der Verknüpfungstabelle hinzu.
Ein Nachteil davon ist, dass es nicht die Anzahl der Bedingungen für jedes Paar angibt. Eine andere ist, wenn ich nur über die anfängliche Beziehung zu etwas wie nachdenke
SELECT objx.*, objy.* FROM objx
INNER JOIN objx_objy ON objx_objy.x_id = objx.id
INNER JOIN objy ON objy.id = objx_objy.y_id
Ich muss dann eine DISTINCT
Klausel hinzufügen , um doppelte Einträge zu vermeiden. Dies scheint die Tatsache verloren zu haben, dass jedes Paar nur einmal existieren sollte.
Option 3
Erstellen Sie eine neue 'Paar-ID' in der Verknüpfungstabelle und erstellen Sie eine zweite Verknüpfungstabelle zwischen der ersten und den Eigenschaften und Bedingungen.
Dies scheint die geringsten Nachteile zu haben, abgesehen von dem Fehlen einer festgelegten Anzahl von Bedingungen für jedes Paar. Ist es sinnvoll, eine neue ID zu erstellen, die nichts anderes als vorhandene IDs identifiziert?
Option 4 (3b)
Grundsätzlich das Gleiche wie Option 3, jedoch ohne die Erstellung des zusätzlichen ID-Feldes. Dies wird erreicht, indem beide ursprünglichen IDs in die neue Verknüpfungstabelle eingefügt werden x_id
und y_id
stattdessen Felder und enthalten xy_id
.
Ein zusätzlicher Vorteil dieses Formulars besteht darin, dass die vorhandenen Tabellen nicht geändert werden (obwohl sie noch nicht in Produktion sind). Im Grunde genommen dupliziert es jedoch eine ganze Tabelle mehrmals (oder fühlt sich sowieso so an) und scheint daher auch nicht ideal zu sein.
Zusammenfassung
Mein Gefühl ist, dass die Optionen 3 und 4 so ähnlich sind, dass ich mit beiden Optionen fahren könnte. Ich hätte wahrscheinlich jetzt, wenn nicht für die Anforderung einer kleinen, festen Anzahl von Links zu Eigenschaften, die Option 1 vernünftiger erscheinen lässt, als es sonst wäre. Basierend auf einigen sehr eingeschränkten Tests DISTINCT
scheint das Hinzufügen einer Klausel zu meinen Abfragen in dieser Situation keine Auswirkung auf die Leistung zu haben, aber ich bin nicht sicher, ob Option 2 die Situation und die anderen darstellt, da durch das Platzieren inhärente Duplikate auftreten Dieselben (X, Y) Paare in mehreren Zeilen der Verknüpfungstabelle.
Ist eine dieser Optionen meine beste Lösung, oder gibt es eine andere Struktur, die ich in Betracht ziehen sollte?
quelle
DISTINCT
Klausel, wurde ich von einer Abfrage wie der am Ende von # 2 zu denken, die Linksx
undy
durch ,xyc
sondern bezieht sich nichtc
... Also , wenn ich(x_id, y_id, c_id)
gezwungenUNIQUE
mit Zeilen(1,1,1)
und(1,1,2)
dannSELECT x.id, y.id FROM x JOIN xyc JOIN y
werde ich wieder zwei identische bekommen Zeilen,,(1,1)
und(1,1)
.Antworten:
Option 1
Abfrage-SQL wird dadurch nicht unbedingt kompliziert (siehe Schlussfolgerung unten).
Es lässt sich leicht auf mehr Bedingungen skalieren, solange es noch eine feste Anzahl von Bedingungen gibt und es nicht Dutzende oder Hunderte gibt.
Das stimmt, und obwohl Sie in einem Kommentar sagen, dass dies "die unwichtigste meiner Anforderungen" ist, haben Sie nicht gesagt, dass es überhaupt keine Rolle spielt.
Option 2Ich denke, Sie können diese Option aufgrund der von Ihnen erwähnten Komplikationen ablehnen. Die
objx_objy
Tabelle ist wahrscheinlich die Ansteuertabelle für einige Ihrer Abfragen (z. B. "Alle auf ein Feature angewendeten Eigenschaften auswählen", womit alle auf einobjx
oder angewendeten Eigenschaften gemeint sindobjy
). Sie können eine Ansicht verwenden, um die vorab anzuwenden,DISTINCT
damit es nicht zu komplizierten Abfragen kommt, aber dies wird sich in Bezug auf die Leistung sehr schlecht skalieren lassen und nur sehr wenig Gewinn bringen.Option 3Nein, das ist nicht der Fall - Option 4 ist in jeder Hinsicht besser.
Option 4
Diese Option ist in Ordnung - es ist die naheliegende Möglichkeit, die Beziehungen einzurichten, wenn die Anzahl der Eigenschaften variabel ist oder sich ändern kann
Fazit
Ich würde Option 1 bevorzugen, wenn die Anzahl der Eigenschaften pro
objx_objy
wahrscheinlich stabil ist und Sie sich nicht vorstellen können, jemals mehr als eine Handvoll Extra hinzuzufügen. Es ist auch die einzige Option, die die Einschränkung 'Anzahl der Eigenschaften = 3' erzwingt - die Erzwingung einer ähnlichen Einschränkung für Option 4 würde wahrscheinlich das Hinzufügen vonc1_p_id
... Spalten zur xy-Tabelle beinhalten *.Wenn Ihnen diese Bedingung wirklich nicht besonders wichtig ist und Sie auch Grund zu der Annahme haben, dass die Bedingung für die Anzahl der Eigenschaften stabil sein wird, wählen Sie Option 4.
Wenn Sie nicht sicher sind, welche, wählen Sie Option 1 - es ist einfacher und das ist definitiv besser, wenn Sie die Option haben, wie andere gesagt haben. Wenn Sie die Option 1 deaktiviert haben, "... weil dies die Auswahl aller auf ein Feature angewendeten Eigenschaften in SQL erschwert ...", empfehle ich, eine Ansicht zu erstellen, die dieselben Daten enthält wie die zusätzliche Tabelle in Option 4:
Option 1 Tische:
Ansicht, um Option 4 zu 'emulieren':
"Alle auf ein Feature angewendeten Eigenschaften auswählen":
dbfiddle hier
quelle
Ich glaube, dass jede dieser Optionen funktionieren könnte, aber ich würde Option 1 wählen, wenn die Anzahl der Bedingungen wirklich auf 3 festgelegt ist, und Option 2, wenn dies nicht der Fall ist. Das Rasiermesser von Occam eignet sich auch für das Datenbankdesign. Bei allen anderen Faktoren ist das einfachste Design in der Regel das beste.
Wenn Sie jedoch strenge Regeln für die Datenbanknormalisierung einhalten möchten, müssen Sie meines Erachtens mit 2 fortfahren, unabhängig davon, ob die Anzahl der Bedingungen festgelegt ist.
quelle