Das Design des zugrunde liegenden Datenmodells, das geografische Standorte innerhalb einer Anwendung darstellt, schlägt zwei klare Optionen vor (oder vielleicht mehr?).
Eine Tabelle mit einer selbstreferenzierenden parent_id-Spalte uk - london (london parent id = UK id)
oder zwei Tabellen mit einer Eins-zu-Viele-Beziehung unter Verwendung eines Fremdschlüssels.
Ich bevorzuge eine selbstreferenzierende Tabelle, da sie problemlos die Erweiterung auf beliebig viele Unterregionen ermöglicht.
Im Allgemeinen weichen die Leute von selbstreferenzierenden Tabellen ab, oder sind sie A-OK?
sql
database-design
NimChimpsky
quelle
quelle
hierarchyid
Typ eingeführt.Nekromanzierung.
Die richtige Antwort lautet: Es kommt darauf an, welche Datenbank-Engine und welches Management-Tool verwendet wird.
Lassen Sie uns ein Beispiel machen:
Wir haben eine Berichtstabelle,
und ein Bericht kann ein übergeordnetes Element haben (Menüpunkt, wie Kategorie),
und dieses übergeordnete Element kann selbst ein übergeordnetes Element haben (z. B. Profit Center)
und so weiter.
Das einfachste Beispiel für eine standardmäßige rekursive Beziehung, wie bei jeder selbstreferenzierenden Entität / Hierarchie.
Die resultierende SQL-Server-Tabelle lautet:
Aber Sie bekommen ein Problem:
Wenn Sie einen Menupunkt mit all seinen Unterpunkten löschen müssen, können Sie delete-cascade NICHT setzen, weil Microsoft SQL-Server rekursive kaskadierte Löschvorgänge nicht unterstützt (PostGreSQL hingegen [, aber nur wenn graph is not cyclic], während MySQL diese Art von Tabellenstruktur überhaupt nicht mag, weil es keine rekursiven CTEs unterstützt).
Sie können damit also die Löschintegrität / -funktionalität in die Luft jagen, sodass die Implementierung dieser Funktionalität in Ihrem eigenen Code oder in einer gespeicherten Prozedur (sofern Ihr RDBMS gespeicherte Prozeduren unterstützt) obligatorisch ist.
Dies wird zweifellos jede Art von vollautomatischem dynamischem Datenimport / -export in die Luft jagen, da Sie weder einfach eine Löschanweisung für alle Tabellen gemäß (nicht selbstreferenzierenden) Fremdschlüsselbeziehungen ausführen noch eine einfache Auswahl vornehmen können * und erstellen Sie eine Einfügung für jede Zeile in einer beliebigen Reihenfolge.
Wenn Sie beispielsweise ein INSERT-Skript mit SSMS erstellen, erhält SSMS den Fremdschlüssel nicht und erstellt daher tatsächlich Insert-Anweisungen, mit denen Einträge mit Abhängigkeiten eingefügt werden, bevor das übergeordnete Element der Abhängigkeit eingefügt wird, was mit einem Fehler fehlschlägt , weil der Fremdschlüssel vorhanden ist.
Auf ordnungsgemäßen Datenbankverwaltungssystemen (wie PostgreSQL) sollte dies jedoch mit geeigneten Tools kein Problem darstellen. Nur verstehen, dass nur, weil Sie viel für Ihr RDBMS (ich sehe Sie, Microsoft; Oracle =?) Und / oder dessen Tool-Belt bezahlen, es nicht bedeutet, dass es richtig programmiert ist. Und OpenSource (zB MySQL) macht Sie auch nicht immun gegen solch wunderbare Kleinigkeiten.
Der Teufel steckt im Detail, wie das alte Sprichwort sagt.
Nun, nicht, dass Sie solche Probleme nicht umgehen könnten, aber ich würde es wirklich nicht empfehlen, wenn Ihr System komplex sein wird (z. B. mehr als 200 Tabellen).
Außerdem wird Ihnen in einem üblichen kommerziellen Umfeld (wie von Dilbert dargestellt) diese Zeit nicht gewährt.
Ein viel besserer, wenn auch schwierigerer Ansatz wäre ein Abschlusstisch.
Das hätte den zusätzlichen Bonus, dass es auch auf MySQL funktioniert.
Sobald Sie die Closure-Funktionalität einmal implementiert haben, können Sie sie in kürzester Zeit an weiteren Stellen einsetzen.
quelle
Es ist eine gute Idee, wenn die Beziehung tatsächlich hierarchisch und keine Netzwerkbeziehung ist (z. B. ist eine Stückliste eine Netzwerkbeziehung, keine hierarchische).
Die Abfrage kann langsam sein. Um die Dinge zu beschleunigen, können Sie eine Closure Table verwenden.
http://karwin.blogspot.ca/2010/03/rendering-trees-with-closure-tables.html
quelle