Ich habe eine PHP-Webanwendung, die eine MySQL-Datenbank für die Objektkennzeichnung verwendet, in der ich die Tag-Struktur verwendet habe, die als Antwort auf diese SO Frage .
Ich möchte eine Tag-Hierarchie implementieren, bei der jedes Tag ein eindeutiges Eltern-Tag haben kann. Die Suche nach einem Eltern-Tag T würde dann mit allen Nachkommen von T übereinstimmen (d. H. T, Tags, deren Eltern T (Kinder von T), Enkel von T usw. sind.)
Am einfachsten ist es, wenn Sie der Tag-Tabelle ein ParentID-Feld hinzufügen, das die ID des übergeordneten Tags eines Tags enthält, oder eine magische Zahl, wenn das Tag kein Elternelement hat. Die Suche nach Nachkommen erfordert jedoch wiederholte wiederholte Suchen in der Datenbank, um die Tags in jeder Generation zu finden, die ich vermeiden möchte.
Eine (vermutlich) schnellere, aber weniger normalisierte Art, dies zu tun, wäre, eine Tabelle zu haben, die alle Kinder jedes Tags oder sogar alle Nachkommen jedes Tags enthält. Dies birgt jedoch das Risiko inkonsistenter Daten in der Datenbank (z. B. ein Tag, der das Kind von mehr als einem Elternteil ist).
Gibt es eine gute Möglichkeit, Abfragen zu erstellen, um Nachkommen schnell zu finden, während die Daten so normal wie möglich gehalten werden?
Alis Antwort hat einen Link zu Joe Celkos Bäumen und Hierarchien in SQL für Smarties , die bestätigt meinen Verdacht - es gibt keine einfache Datenbankstruktur, die das Beste aus allen Welten bietet. Das beste für meinen Zweck scheint der in diesem Buch beschriebene "Frequency Insertion Tree" zu sein, der wie das "Nested Set Model" von Alis Link ist, aber mit nicht aufeinander folgender Indexierung. Dies ermöglicht O (1) -Einfügung ( a la unstrukturierte BASIC-Zeilennummerierung) mit gelegentlicher Indexreorganisation bei Bedarf.
Ich habe es mit zwei Spalten implementiert. Ich vereinfach es hier ein wenig, weil ich den Tag-Namen in einem separaten Feld / Tabelle behalten musste, weil ich es für verschiedene Sprachen lokalisieren musste:
Betrachten Sie diese Zeilen zum Beispiel:
%Vor%usw.
Mit dem Operator like
im Pfadfeld können Sie einfach alle benötigten Tag-Zeilen erhalten:
Es gibt einige Implementierungsdetails, wie wenn Sie einen Knoten in der Hierarchie verschieben, müssen Sie auch alle Kinder usw. ändern, aber es ist nicht schwer.
Stellen Sie außerdem sicher, dass die Länge Ihres Pfades lang genug ist - in meinem Fall habe ich nicht den Tag-Namen für den Pfad verwendet, sondern ein anderes Feld, um sicherzustellen, dass ich keine zu langen Pfade bekomme.
Sie könnten das erstellen, was Kimball eine Hierarchie-Hilfstabelle nennt.
Sagen Sie, Ihre Hierarchie sieht so aus: A - & gt; B | B - & gt; C | C - & gt; D
Sie würden Datensätze in eine Tabelle einfügen, die so aussieht
ParentID, ChildID, Tiefe, Höchste Flagge, Niedrigste Flagge
A, A, 0, Y, N
A, B, 1, N, N
A, C, 2, N, N
A, D, 3, N, Y
B, B, 0, N, N
B, C, 1, N, N
B, D, 2, N, Y
C, C, 0, N, N
C, D, 1, N, Y
D, D, 0. N, Y
Ich denke, ich habe das richtig ... jedenfalls. Der Punkt ist, dass Sie Ihre Hierarchie immer noch korrekt speichern, Sie erstellen diese Tabelle einfach aus Ihrer eigenen Tabelle. Diese Tabelle fragt wie ein Banshee ab. Angenommen, Sie möchten wissen, was die erste Ebene unter B ist.
WHERE parentID = 'B' und Tiefe = 1
Ich würde eine Art Array verwenden, um die Child-Tags zu speichern, das sollte viel schneller sein als das Hinzufügen einer Tabelle zu sich selbst (besonders wenn Sie eine große Anzahl von Tags haben). Ich habe nachgesehen, und ich kann nicht sagen, ob MySQL einen nativen Array-Datentyp hat, aber Sie können dies emulieren, indem Sie eine Textspalte verwenden und ein serialisiertes Array darin speichern. Wenn Sie die Dinge noch weiter beschleunigen möchten, sollten Sie in der Lage sein, einen Textsuchindex für diese Spalte festzulegen, um herauszufinden, welche Tags verwandt sind.
[Bearbeiten] Nachdem ich Alis Artikel gelesen hatte, machte ich noch mehr Jagd und fand diese Präsentation über eine Reihe von Ansätzen zur Implementierung von Hierarchien in Postgres . Könnte immer noch zu Erklärungszwecken hilfreich sein.
Tags und Links sql mysql database tags normalizing