teddy86: Rekursives Auslesen von Datenbanken mit PHP

Guten Tag!

Ich habe folgendes Problem, bei dem ich für jeden Lösungsansatz dankbar bin:

Datensätze in einer Datenbank sind mit einer ID und einer parentID ausgestattet. ID ist der autoincrement-Wert und dient zur Identifikation eines Menüeintrages. Dieser Menüeintrag hat Untermenüpunkte.

Ich möchte nun alle IDs der Untermenüpunkte auslesen die zum Hauptmenüpunkt gehören (die bei denen parentID gleich der ID des Hauptmenüpunktes ist).

Des weiteren wiederunm auch alle IDs die als parentID die ID der Untermenüpunkte erster Ebene haben.

Ich hoffe ihr versteht was ich meine. Wie löse ich dieses Problem am besten mit einer rekursieven Funktion?

lg teddy

  1. Moin!

    Datensätze in einer Datenbank sind mit einer ID und einer parentID ausgestattet. ID ist der autoincrement-Wert und dient zur Identifikation eines Menüeintrages. Dieser Menüeintrag hat Untermenüpunkte.

    Ich möchte nun alle IDs der Untermenüpunkte auslesen die zum Hauptmenüpunkt gehören (die bei denen parentID gleich der ID des Hauptmenüpunktes ist).

    Des weiteren wiederunm auch alle IDs die als parentID die ID der Untermenüpunkte erster Ebene haben.

    Es ist aus Performancegründen hinsichtlich der Datenbank sehr sinnvoll, jedem Datensatz noch ein zusätzliches Feld für die Zugehörigkeit zum Hauptmenüpunkt zu geben.

    Du selektierst dann alle Datensätze, die zum Hauptmenüpunkte gehören, und kannst das DB-Ergebnis dann mit PHP in eine rekursive Datenstruktur einsortieren lassen.

    Eventuell hilfreich wäre auch noch ein Datenfeld "Tiefe", welches den Abstand des Datensatzes von seiner Wurzel enthält. Diese zwei zusätzlichen Felder sind zwar im Prinzip redundant, da die darin enthaltenen Informationen sich auch direkt aus der Tabelle ermitteln lassen könnten, aber relationale Datenbanken sind nur ganz schlecht auf rekursive Datenstrukturen eingerichtet und bestrafen die Abwesenheit von Redundanzinformationen mit der Notwendigkeit, viele einzelne Abfragen machen zu müssen - welche dann wiederum viel Performance kosten und nur sehr kleine Ergebnismengen bringen - also ein schlechtes Aufwand-Ergebnis-Verhältnis haben.

    - Sven Rautenberg

    --
    My sssignature, my preciousssss!
    1. Bin noch nicht weiter.. Trotzdem danke. Hier mal der Code:

      $resID = mysql_query("SELECT kategorieID FROM shop_kategorien WHERE parentID='$kategorieID' ORDER BY kategorie", $GLOBALS['linkID'])or die(mysql_error());
      while($zeile = mysql_fetch_array($resID,MYSQL_BOTH)){
        $kategorien[] = $zeile["kategorieID"];
      }

      Damit erzeuge ich folgendes Array:

      Array ( [0] => 6 [1] => 10 [2] => 7 [3] => 8 [4] => 9 [5] => 2 [6] => 11 )

      Nun sollen weitere IDs gefunden werden, die die IDs 6, 10, 7, usw. als parentID haben. Diese IDs sollen wieder auf unterpunkte geprüft werden. Dies solange, bis es keine Kinderelemente mehr gibt..

      Das muss unbedingt so und nicht anders gemacht werden. Nachher brauche ich alle IDs in einem Array. Wer kann mir helfen?

      Gruß teddy

  2. echo $begrüßung;

    Datensätze in einer Datenbank sind mit einer ID und einer parentID ausgestattet.

    Du hast sozusagen einen Baum.

    Ich hoffe ihr versteht was ich meine.

    Ja, du möchtest Teile des Baumes auslesen.

    Wie löse ich dieses Problem am besten mit einer rekursieven Funktion?

    Rekursive Anfragen auf eine Datenbank loszulassen ist nicht gerade die optimale Lösung. Nested Sets wäre eine Lösung, die einfachere Abfragen zulässt, aber mehr Aufwand beim Ändern bedeutet.

    Beides wurde schon des öfteren nachgefragt, beispielsweise hier: </archiv/2006/3/t126324>

    echo "$verabschiedung $name";

  3. Hello,

    Das Problem dabei ist wahrscheinlich die Leserichtung.

    Gehst Du vom untergeordneten Element aus, und suchst den Pfad zur Wurzel?
    Oder gehst Du von der Wurzel aus, und suchst die Kindelemente.

    Da es hier um die Darstellung geht, benötigst Du sowieso einiges an Speicher in der Schnittstelle. Da Deine Schnittstelle nun auch noch intelligent ist, gehst Du beim Lesen von der Wurzel einfach folgendermaßen vor:

    Lese alle Sätze des Filterbereiches (Id und Parent) Level = 0
    Lese alle Sätze, deren Parent in der Liste der IDs von Level 0 steckt (ID und Parent) Level = 1
    Lese alle Sätze, deren Parent in der Liste der IDs von Level 1 steckt (ID und Parent) Level = 2

    bis Du keine Sätze mehr bekommst.
    Der Zusammenbau der Struktur im Speicher (als "Array") kostet weniger als ein Tausendstel gegenüber dem Lesen aus der DB.

    Das ist dann pro Ebene ein Query.

    Bei echter Rekursion könnten es leicht hunderte von Queries werden oder gar Tausende.

    Harzliche Grüße vom Berg
    http://www.annerschbarrich.de

    Tom

    --
    Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
    Nur selber lernen macht schlau