Pullmann hat gesagt.:
Hallo ,
ich habe folgendes Problem und zwar brauche ich ein Submenu das beliebig viele Ebenen haben soll .
Main
-Subeins
--Subsubzwei
---Subsubdre
-Subzwei
--Subsubzwei
und so weiter ... es soll also so sein das jedes Submenu ein Submenu beinhalten kann !
Weis einer wie man sowas macht oder wonach ich suchen muss um das zu lösen
Also hierfür gibt es zwei verschiedene Methoden:
Die eine, an sich schnell und einfach umzusetzende Methode ist das Parent-ID-Modell. Du legst eine Tabelle mit mindestens 3 Spalten an:
- id (auto_increment)
- title (text für den jeweiligen menüpunkt)
- parent_id (übergeordneter menüpunkt)
So, alle Hauptmenüpunkte haben in der Spalte "parent_id" eine 0 stehen, d.h. alle diese Datensätze in der Datenbank sind an oberster Ebene in Menü angeordnet.
Also beispielsweise so:
Code:
+----+-------------+-----------+
| id | text | parent_id |
+----+-------------+-----------+
| 1 | menü 1 | 0 |
+----+-------------+-----------+
| 2 | menü 2 | 0 |
+----+-------------+-----------+
Wenn Du jetzt dem Menü 1 weitere Untermenüpunkte zuordnen willst, musst Du allen diesen Datensätze als Parent-ID die ID vom Menüpunkt 1 zuordnen (in diesem Fall die 1). Das sieht dann in der Datenbank so aus:
Code:
+----+-------------+-----------+
| id | text | parent_id |
+----+-------------+-----------+
| 1 | menü 1 | 0 |
+----+-------------+-----------+
| 2 | menü 2 | 0 |
+----+-------------+-----------+
| 3 | sub 1.1 | 1 |
+----+-------------+-----------+
| 4 | sub 1.2 | 1 |
+----+-------------+-----------+
| 5 | sub 1.3 | 1 |
+----+-------------+-----------+
Das gleiche kannst Du jetzt natürlich auch analog für den zweiten Menüpunkt machen. Nur musst dann natürlich die entsprechende ID vom zweiten Menüpunkt als Parent-ID abgespeichert werden. Diesen Untermenüpunkten kannst Du natürlich auch wiederum weitere Untermenüpunkte zuordnen. Einfach als Parent-ID die jeweilige ID vom gewünschten Untermenüpunkt, unter dem der weiter Untermenüpunkt (der 3. Ebene) zugeordnet werden soll, abspeichern.
So, und jetzt willst Du das ganze natürlich auslesen und darstellen. Du liest dann erstmal alle Hauptmenüpunkte aus der Datenbank, und lässt diese mittels einer Schleife ausgeben. Bei jedem Schleifendurchlauf musst Du jetzt allerdings wieder erneut eine SQL-Anfrage an die Datenbank schicken um zu prüfen, ob es für den jeweiligen Menüpunkt weitere Untermenüpunkte gibt, sprich: in einer rekursiven Funktion lässt Du dir Stück für Stück das Menü ausgeben. Und hier siehst Du auch schon den Nachteil bei dieser Methode. Hast Du nur ein kleines Menü mit einer überschaubaren Struktur, dann ist es kein Problem und das Menü sollte schnell ausgelesen werden. Wenn das Menü allerdings viele Haupt- und Untermenüpunkte enthalten soll, dann kann das ganze schon ordentlich auf die Performance gehen.
Als alternative dazu gibt es das NestedSet Modell. Hier is die Tabellenstruktur ein weniger trickreicher. In der Menütabelle hast Du nachwievor die Spalte "id" und die Spalte "title". Die Spalte "parent_id" fällt hier weg, dafür gibt es zwei neue Spalten: "left" und "right".
Wenn Du dir jetzt mal dein Menü (= Baum) vorstellst, so ist "Main" die Wurzel des Baumes (= Root). Dieser Wurzel werden jetzt nacheinader weitere Untermenüpunkte ( = Äste, bzw. Children) angefügt. Und hierbei kommen die beiden Spalten "left" und "right" ins Spiel. Diese Werte definieren, wie man durch den ganzen Baum gehen soll. Dabei legen diese Werte sowohl die Zuordnung verschiedener Äste (= Childens) fest, als auch deren Reihenfolge innerhalb des Astes.
Zugegeben, das ganze Prinzip ist auf den ersten Blick etwas komplitziert im vergleich zum Parent-ID Modell. Ein Bild [1] sagt mehr als Worte:
Aber auch diese Methode ist nicht perfekt: Da alle Werte in den "left" und "right" Spalten von einander abhängig sind, muss mann, wenn man einen weiteren Menüpunkt hinzufügen oder löschen will, unter umständen ALLE Datensätze aktualisieren. Aber dafür bietet das NestedSet Modell einen ganz klaren Vorteil: Mit nur einer einzigen SQL-Anfrage bekomme ich den kompletten Menübaum zurück inkl. dem jeweiligen Level (= Menüebene) des jeweiligen Menüpunktes. Somit liegt es auf der Hand, dass das NestedSet Modell den Vorteil beim Lesen hat. Wird die Menüstruktur oft geändert bzw. aktualisiert, muss man abwägen, ob der Einsatz von Nested Sets ebenfalls erforderlich ist.
Fazit: Man muss unbedingt abwägen, welches Modell das passende ist. Dabei spielt zum einen die Größe des Menüs und die Tiefe der Verschachtelung eine Rolle. Zum anderen sollte man aber auch beachten, ob dem Menü oft neue Menüpunkte hinzugefügt oder alte Menüpunkte gelöscht werden sollen.
[1]
Das 'Nested Sets' Modell - Bäume mit SQL