Was sind die Optionen für die Speicherung von hierarchischen Daten in einer relationalen Datenbank?
Gute Übersichten
Generell, Sie machen eine Entscheidung zwischen schnell mal Lesen (zum Beispiel, nested set) oder schnell mal schreiben (angrenzens Liste). In der Regel werden Sie am Ende mit einer Kombination der folgenden Optionen, die am besten zu Ihren Bedürfnissen passen. Im folgenden werden einige in-Tiefe Lesung:
- Eine weitere Geschachtelte Intervalle vs. Nähe-Liste Vergleich: der beste Vergleich der Nähe Liste, Materialized Path, Geschachtelten und Verschachtelte Intervall den ich gefunden habe.
- Modelle für hierarchische Daten: Folien mit guten Erklärungen der Nachteile und Beispiel für die Verwendung
- Die Darstellung der Hierarchien in MySQL: sehr gute übersicht von Geschachtelten insbesondere
- Hierarchische Daten in RDBMS: die meisten umfassende und gut organisierte Sammlung von links, die ich gesehen habe, aber nicht viel in der Weise der Erklärung
Optionen
Denen ich mir bewusst bin-und Allgemeine Funktionen:
- Nähe Liste:
- Spalten: ID, ParentID
- Einfach zu implementieren.
- Billig-Knoten bewegt, Einfügungen und Löschungen.
- Teuer zu finden, die Ebene, Abstammung & Nachkommen, Pfad
- Vermeiden N+1 über Common Table Expressions in Datenbanken, die Sie unterstützen
- Nested Set (ein.k.ein Modified Preorder Tree Traversal)
- Spalten: Links, Rechts
- Billig Abstammung, Nachkommen
- Sehr teuer
O(n/2)
bewegt, Einfügungen, Löschungen aufgrund des volatilen Codierung
- Bridge-Tabelle (ein.k.ein. Schließung Tabelle /w-Trigger)
- Verwendet separate join-Tabelle: Vorfahren, Nachkommen, Tiefe (optional)
- Günstigen Vorfahren und Nachkommen
- Schreibt Kosten
O(log n)
(Größe Teilbaum) für einfügen, aktualisieren, löschen - Normalisierte Kodierung: gut für die RDBMS-Statistiken & query planner schließt
- Erfordert mehrere Zeilen pro Knoten
- Abstammung Spalte (ein.k.ein. Materialized Path, Path Enumeration)
- Spalte: Linie (z.B. /Eltern/Kind/Enkel/etc...)
- Billig Nachkommen über prefix-Abfrage (z.B.
LEFT(lineage, #) = '/enumerated/path'
) - Schreibt Kosten
O(log n)
(Größe Teilbaum) für einfügen, aktualisieren, löschen - Nicht-relationale: basiert auf Array-Datentyp oder serialisierte string-format
- Geschachtelte Intervalle
- Wie verschachtelte Satz, aber mit real/float/decimal, so dass die Codierung nicht flüchtig (preiswert verschieben/einfügen/löschen)
- Hat real/float/decimal-Darstellung/Präzisions-Themen
- Matrix-Codierung-Variante fügt Vorfahren Codierung (materialized path) für "frei", aber mit zusätzlichen trickiness der linearen algebra.
- Flat Tisch
- Eine modifizierte Nachbarschaft-Liste, fügt ein Level und Rang (z.B. Bestellung) - Spalte jedes Datensatzes.
- Billig zu iterieren/paginieren über
- Teuer, verschieben und löschen
- Gut Verwenden: Gewinde-Diskussion - Foren /blog-Kommentare
- Mehrere herkunftsspalten
- Spalten: eine für jede Linie Ebene bezieht sich auf alle Eltern, die bis zu der Wurzel, werden die Ebenen nach unten aus dem Element s-Ebene auf NULL gesetzt
- Günstigen Vorfahren, Nachkommen, Ebene
- Günstigen einfügen, löschen, verschieben der Blätter
- Teuer, einfügen, löschen, verschieben von dem internen Knoten
- Hart an der Grenze, wie tief die Hierarchie
Datenbank-Spezifische Hinweise
MySQL
Oracle
- Verwenden VERBINDEN zu durchqueren Angrenzens Listen
PostgreSQL
- ltree Datentyp für Materialized Path
SQL Server
- Allgemeine Zusammenfassung
- 2008 bietet HierarchyId Daten Typ scheint zu helfen, mit Abstammung Spalte Ansatz und erweitern die Tiefe dargestellt werden kann.
Nach slideshare.net/billkarwin/sql-antipatterns-strike-back Seite 77
Ich vermisse eine sehr einfache version hier: eine einfache BLOB. Wenn Ihre Hierarchie nur noch ein paar dozend Elemente, die einen serialisierten Baum von id ' s könnte die beste option sein.
Frage ist ein community-wiki, so fühlen sich frei, um es haben. Mein Gedanke dabei: ich würde es nur tun, die mit den Datenbanken unterstützen eine Art von blob-Strukturierung, wie Sie XML mit einem stabilen Anfragesprache wie XPATH. Ansonsten sehe ich nicht ein guter Weg, von der Abfrage abgesehen von abrufen, Deserialisieren und munge im code, nicht SQL. Und wenn du wirklich ein problem, wo Sie brauchen, eine Menge von beliebigen Elementen könnten Sie besser dran, mit Knoten wie bei einer Datenbank Neo4J, die ich jemals benutzt habe und mochte, wenn auch nie bis zur Produktion.
Für MS SQL Server: Kombination von Id-ParentId-und HierarchyId-Ansätze für Hierarchische Daten
Die MSDN-link für den "Allgemeinen Zusammenfassung" nicht mehr zeigt der Artikel. Es wurde in der September 2008-Ausgabe des MSDN Magazins, die Sie herunterladen können, als eine CHM-Datei, oder sehen Sie über das web-Archiv unter: web.archive.org/web/20080913041559/http://msdn.microsoft.com:80/...
Closure Tables
überlegen sind Adjacency List
, Path Enumeration
und Nested Sets
in Bezug auf die Benutzerfreundlichkeit (und ich vermute, die Leistung sowie).Ich vermisse eine sehr einfache version hier: eine einfache BLOB. Wenn Ihre Hierarchie nur noch ein paar dozend Elemente, die einen serialisierten Baum von id ' s könnte die beste option sein.
Frage ist ein community-wiki, so fühlen sich frei, um es haben. Mein Gedanke dabei: ich würde es nur tun, die mit den Datenbanken unterstützen eine Art von blob-Strukturierung, wie Sie XML mit einem stabilen Anfragesprache wie XPATH. Ansonsten sehe ich nicht ein guter Weg, von der Abfrage abgesehen von abrufen, Deserialisieren und munge im code, nicht SQL. Und wenn du wirklich ein problem, wo Sie brauchen, eine Menge von beliebigen Elementen könnten Sie besser dran, mit Knoten wie bei einer Datenbank Neo4J, die ich jemals benutzt habe und mochte, wenn auch nie bis zur Produktion.
Für MS SQL Server: Kombination von Id-ParentId-und HierarchyId-Ansätze für Hierarchische Daten
Die MSDN-link für den "Allgemeinen Zusammenfassung" nicht mehr zeigt der Artikel. Es wurde in der September 2008-Ausgabe des MSDN Magazins, die Sie herunterladen können, als eine CHM-Datei, oder sehen Sie über das web-Archiv unter: web.archive.org/web/20080913041559/http://msdn.microsoft.com:80/...
InformationsquelleAutor |
Du musst angemeldet sein, um einen Kommentar abzugeben.
Meine Lieblings-Antwort ist als das, was der erste Satz in diesem thread vorgeschlagen. Verwenden Sie ein Angrenzens Liste, die Hierarchie zu halten und verwenden Sie Verschachtelte Sätze, zum Abfragen der Hierarchie.
Das problem war bis jetzt, dass die coversion-Methode von einem Adjacecy Liste zu Nested Sets wurde furchtbar langsam, weil die meisten Menschen nutzen die extreme RBAR Methode bekannt als "Push-Stapel", um die Konvertierung und wurde als viel zu teuer zu erreichen das Nirwana der Einfachheit der Wartung durch die Nähe Liste und die tolle Leistung von Nested Sets. Als Ergebnis, die meisten Menschen müssen, um sich für die eine oder die andere, besonders wenn es mehr als, sagen wir, eine lausige 100.000 Knoten oder so. Mit der push-stack Methode kann einen ganzen Tag, um die Konvertierung zu tun, was MLM ' ers würden erwägen, um eine kleine Millionen-Knoten-Hierarchie.
Ich dachte, ich würde geben Celko ein bisschen Wettbewerb durch kommen mit einer Methode zum konvertieren eines Angrenzens Liste zu Nested sets bei Geschwindigkeiten, die scheinen einfach unmöglich. Hier ist die Leistung des push-stack Methode auf meinem i5 laptop.
Und hier ist die Dauer für die neue Methode (mit der push-stack Methode in Klammern).
Ja, das ist richtig. 1 Millionen Knoten umgewandelt in weniger als einer minute und 100.000 Knoten in unter 4 Sekunden.
Können Sie Lesen Sie über die neue Methode und eine Kopie des Codes unter der folgenden URL.
http://www.sqlservercentral.com/articles/Hierarchy/94040/
Ich entwickelte auch eine "pre-aggregierten" Hierarchie mit ähnlichen Methoden. MLM ' ers und die Leute, die Stücklisten werden vor allem Interessierte in diesem Artikel.
http://www.sqlservercentral.com/articles/T-SQL/94570/
Wenn Sie von zu stoppen, um einen Blick auf entweder den Artikel, den Sprung in die "diskutieren" - link und lassen Sie mich wissen, was Sie denken.
InformationsquelleAutor
Dies ist eine sehr partielle Antwort auf deine Frage, aber ich hoffe immer noch nützlich.
Microsoft SQL-Server 2008 implementiert zwei Funktionen, die sehr nützlich sind für die Verwaltung von hierarchischen Daten:
Haben Sie einen Blick auf "Modellieren Sie Ihre Daten Hierarchien Mit SQL Server 2008" von Kent Tegels auf der MSDN-Website für beginnt. Siehe auch meine eigene Frage: Rekursive gleichen-table-Abfrage in SQL Server 2008
In der Tat. Ich arbeite mit einer Menge von rekursiv-hierarchische Daten, und ich finde, common table expressions äußerst nützlich. Siehe msdn.microsoft.com/en-us/library/ms186243.aspx für ein intro.
InformationsquelleAutor CesarGon
Dieser Entwurf wurde noch nicht erwähnt:
Mehrere herkunftsspalten
Obwohl es seine Grenzen hat, wenn Sie tragen können, Sie, es ist sehr einfach und sehr effizient. Features:
Hier folgt ein Beispiel - taxonomischen Baum der Vögel sind, so dass die Hierarchie-Klasse/Ordnung/Familie/Gattung/Spezies - Spezies ist die niedrigste Ebene 1 row = 1 taxon (das entspricht Art in der Fall of the leaf nodes):
am Beispiel der Daten:
Das ist großartig, denn auf diese Weise erreichen Sie alle notwendigen Operationen auf sehr einfache Weise, wie lange, wie die internen Kategorien ändern sich nicht Ihrer Ebene in der Struktur.
InformationsquelleAutor
Angrenzens Modell + Nested Sets Modell
Ich ging für Sie, weil ich könnte das einfügen neuer Elemente zu dem Baum leicht (Sie brauchen nur ein Zweig-id einfügen eines neuen Elements) und auch Abfrage, es ganz schnell.
parent
Spalte.lft
zwischenlft
undrgt
Eltern.lft
niedriger als der Knotenlft
undrgt
größer als der Knotenrgt
und Sortieren vonparent
., Die ich brauchte, um Zugriff auf die und Abfrage der Baum schneller als Einlagen, das ist, warum ich wählte dieses
Das problem ist nur zu beheben, die
left
undright
Spalten beim einfügen neuer Elemente. naja ich erstellt eine gespeicherte Prozedur für es und nannte es jedes mal, wenn ich ein neues Element eingefügt, das war selten in meinem Fall ist es aber wirklich schnell.Ich habe die Idee von Joe Celko ' s Buch, und die gespeicherte Prozedur, und wie ich kam mit ihm hier erklärt wird im DBA-SE
https://dba.stackexchange.com/q/89051/41481
Dies ist eine interessante Lösung, allerdings bin ich mir nicht sicher, dass das Abfragen des parent-Spalte bietet wirklich keine großen Vorteile, wenn Sie versuchen zu finden, Kinder -- deshalb haben wir für den linken und rechten Spalten, in den ersten Platz.
es gibt einen Unterschied zwischen
children
unddescendants
.left
undright
werden verwendet, um die Nachkommen.InformationsquelleAutor
Wenn Ihre Datenbank unterstützt arrays, Sie können auch implementieren Sie eine Linie Spalte oder materialisierte Pfad als array des parent-ids.
Speziell mit Postgres verwenden Sie dann die set-Operatoren zum Abfragen der Hierarchie, und erhalten Sie ausgezeichnete Leistung mit GIN-Indizes. Dies macht die Suche nach Eltern, Kinder und Tiefe ziemlich trivial in einer einzigen Abfrage. Updates sind ziemlich überschaubar als gut.
Habe ich eine volle schreiben, der mit arrays für die materialisierte Pfade wenn du neugierig bist.
InformationsquelleAutor
Dies ist wirklich ein square peg, Runde Loch Frage.
Wenn relationale Datenbanken und SQL sind die nur der hammer Sie haben oder bereit sind, Sie zu verwenden, dann die Antworten, die gepostet wurden, so weit angemessen. Aber warum nicht ein tool verwenden, das entworfen, um hierarchische Daten? Graph-Datenbank sind ideal für komplexe hierarchische Daten.
Den Unzulänglichkeiten des relationalen Modells zusammen mit der Komplexität von code/query-Lösung zum anzeigen einer Kurve/hierarchische Modell auf ein relationales Modell ist einfach nicht der Mühe Wert, wenn im Vergleich zu der Leichtigkeit, mit der eine graph Datenbank-Lösung für das gleiche problem.
Betrachten Sie eine Stückliste als eine gemeinsame hierarchische Datenstruktur.
Kürzesten Weg zwischen zwei Baugruppen: Einfacher graph-traversal Algorithmus. Pfade zulässig qualifiziert werden kann, basierend auf Kriterien.
Ähnlichkeit: Was ist der Grad der ähnlichkeit zwischen zwei Baugruppen? Führen Sie eine traversal auf beiden sub-Bäume Berechnung der Schnittmenge und Vereinigung der beiden sub-Bäume. Die Prozent, ähnlich ist die Schnittmenge geteilt durch die union.
Transitive Abschluss: Walk the sub-tree und die Summe der field(s) of interest, z.B. "Wie viel Aluminium ist in einem sub-assembly?"
Ja, Sie können das problem lösen mit SQL und relationalen Datenbanken. Allerdings gibt es viel bessere Ansätze, wenn Sie bereit sind, verwenden Sie das richtige Werkzeug für den job.
SPARQL ist relevant für RDF-Datenbanken, die eine Unterklasse der größeren Domäne von graph-Datenbanken. Ich arbeite mit InfiniteGraph, die nicht einer RDF-Datenbank und bietet zurzeit keine Unterstützung für SPARQL. InfiniteGraph unterstützt verschiedene Abfrage-Mechanismen: (1) ein graph navigation API für das einrichten von Ansichten, Filter, Pfad Qualifikations-und Ergebnis-Handler, (2) eine komplexe graph-path pattern matching Sprache, und (3) Gremlin.
InformationsquelleAutor
Ich bin mit PostgreSQL mit Verschluss-Tabellen für mein Hierarchien.
Ich habe eine universal-gespeicherte Prozedur, die für die gesamte Datenbank:
Dann für jede Tabelle, wo ich eine Hierarchie, bei der ich einen trigger erstellen
Für das Auffüllen einer Schließung Tabelle aus vorhandenen Hierarchie ich diese gespeicherte Prozedur verwenden:
Schließung Tabellen definiert sind, mit 3 Spalten - ANCESTOR_ID, DESCENDANT_ID, TIEFE. Es ist möglich (und ich auch Beratung) zum speichern der Datensätze mit demselben Wert für VORFAHREN und NACHKOMMEN, und ein Wert von null in die TIEFE. Dies wird zu einer Vereinfachung der Abfragen für den Abruf der Hierarchie. Und Sie sind in der Tat sehr einfach:
InformationsquelleAutor