Selbstreferenzierende Bäume - klein - einfach - schnell
Immer wieder stellt sich die Aufgabe aus einer Datenbank eine hierarchische Struktur, also einen Baum zu erstellen.
In der Webprogrammierung sind die häufigsten Aufgaben das Erstellen von Strukturen für Produkte, Rubriken, Themen, Berechtigungen (Gruppen in Gruppen), Seitenstrukturen, usw. Die beiden wohl am meisten verbreiteten Arten zur Abbildung von Bäumen in Datenbanken sind die klassischen Parent - Child Bäume und Nested Sets. Nested Sets sind schick, lesend super schnell aber irgendwie sind sie doch meistens zu kompliziert sobald es dran geht den Baum schreibend zu pflegen. Die klassischen Parent - Child Bäume haben dagegen den Ruf zwar einfach pflegbar, aber im lesenden Zugriff (vor allem auf Teilbäume) eher inperformant zu sein. Oft kommen hier rekursive Funktionen zum Einsatz, vor allem um von einem Blatt wieder zurück zur Root zu kommen. Wenn man den Baum aber "nur" aus Referenzen auf eine "flache" Liste der Knoten aufbaut, hat man damit einen schnellen, einfachen und direkten Zugriff auf alle Teilbäume. Beispiel anhand einer kleinen Tabelle
+----+--------+--------------+ | id | parent | name | +----+--------+--------------+ | 0 | 0 | ROOT | | 1 | 0 | Knoten 1 | | 2 | 0 | Knoten 2 | | 3 | 1 | Knoten 1.1 | | 4 | 1 | Knoten 1.2 | | 5 | 2 | Knoten 2.1 | | 6 | 2 | Knoten 2.1 | | 7 | 3 | Knoten 1.1.1 | | 8 | 3 | Knoten 1.1.2 | +----+--------+--------------+ PHP: Das war's auch schon ;-) Beispiele für den Zugriff: PHP:
Array
(
[name] => ROOT
[childs] => Array
(
[0] => Array
(
[id] => 1
[parent] => 0
[name] => Knoten 1
[childs] => Array
(
[0] => Array
(
[id] => 3
[parent] => 1
[name] => Knoten 1.1
[childs] => Array
(
[0] => Array
(
[id] => 7
[parent] => 3
[name] => Knoten 1.1.1
)
[1] => Array
(
[id] => 8
[parent] => 3
[name] => Knoten 1.1.2
)
)
)
[1] => Array
(
[id] => 4
[parent] => 1
[name] => Knoten 1.2
)
)
)
[1] => Array
(
[id] => 2
[parent] => 0
[name] => Knoten 2
[childs] => Array
(
[0] => Array
(
[id] => 5
[parent] => 2
[name] => Knoten 2.1
)
[1] => Array
(
[id] => 6
[parent] => 2
[name] => Knoten 2.1
)
)
)
)
)
PHP:
Array
(
[id] => 2
[parent] => 0
[name] => Knoten 2
[childs] => Array
(
[0] => Array
(
[id] => 5
[parent] => 2
[name] => Knoten 2.1
)
[1] => Array
(
[id] => 6
[parent] => 2
[name] => Knoten 2.1
)
)
)
Soweit so gut, aber wie kommt man einfach von einem Blatt wieder zurück zum Root? Auch kein Problem, wenn man beim aufbauen des Baumes z.B. bei jeden Knoten ein Array mit den IDs zurück zum root mitschreibt. Natürlich könnte man auch als "back to the root" Info bei jedem Knoten eine Array von Referenzen zu den Elternknoten aufbauen, aber als Beispiel sollen hier mal die IDs reichen. PHP: Dann hat man einfachen Zugriff auf alle Eltern ohne sich mit Rekursionen "rumplagen" zu müssen. PHP: ergibt: Knoten 1.1.2 Knoten 1.1 Knoten 1 ROOT Eigentlich ganz einfach oder? Aber (wie immer) gibt es natürlich auch hier einen Haken: Da immer die komplette Baumstruktur aus der DB gelesen und als Baum aufgebaut werden muss, auch wenn man nur ein kleiner Teilbaum benötigt wird, skaliert diese Methode nicht unendlich. Ab einer gewissen Größe des Baumes sollte man vielleicht doch z.B. Nested Sets verwenden. Ab welcher Größe? Müsste man mal testen, aber ich denke merkliche Unterschiede wird es erst ab ein paar hundert oder tausend Knoten geben. Und ganz ehrlich, meistens sind die Bäume doch eher kleiner oder?
Autor: Jens Giessmann
in DB, PHP
am
Donnerstag, 28. Dezember 2006
um
22:21
Kommentare (0) | Trackbacks (0) Trackbacks
Trackback-URL für diesen Eintrag
Keine Trackbacks
|
blog powered by Serendipity