Ankündigung

Einklappen
Keine Ankündigung bisher.

Baumartige Menü und Datenstruktur

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Baumartige Menü und Datenstruktur

    Hi,
    ich sitz gerade an einem Problem bei dem ich auf keine auch nur einigermaßen gute Lösung komme.

    Es geht um eine Website, welche ein Sitemenü verwendet. Das komplizierte daran ist das die Inhalte des Sitemenüs dynamisch erstellt und kategorisiert werden können.

    Das sieht dann zB. so aus:

    Code:
    1. Hauptgruppe
      1.1 ein Untereintrag
        1.1.1 noch tiefer verschachtelt
        1.1.2  x
        1.1.3  xy
        1.1.4  xyz
      1.2 lalelu - raus bist du
    2. Nu gehts aber los hier
    3. void
      3.1 void me
        3.1.1 morevoids
           3.1.1.1 lookAtThis!
    Das Problem ist das ich die Verschachtelung gern beliebig tief und editierbar erstellen möchte. Deshalb speicher ich das ganze in einer MySQL-Datenbank.

    Hab mir dazu überlegt das jedes Element eine id besitzt, und einen fk (superiorid der die übergeordnete gruppe referenziert:

    Code:
    id | superior | name
    1    1            Hauptgruppe
    2    1            ein Untereintrag
    3    2            noch tiefer verschachtelt
    4    2            x
    8    8            Nu gehts aber los hier
    ...
    Ich denke an diesem kurzen Beispiel ist verständlich wie ich mir das ganze gedacht hab. Hauptgruppen werden einfach dadurch gekennzeichnet, das sie in superior auf sich selbst zeigen.

    Ich möchte das ganze als Ausklappmenü darstellen.
    Also wenn der User Element 1.1.1 auswählt, soll nur der Teilbaum bis dahin und die restlichen Hauptgruppen sichtbar sein.
    (Unterkategorien in diesen sind eingeklappt)

    Habt ihr vielleicht nen sinnvollen Lösungsansatz?

  • #2
    Stichwort: Rekursion

    Die Tabellenstruktur sieht schon mal gut aus.
    [URL]http://hallophp.de[/URL]

    Kommentar


    • #3
      Stichwort: Nested Sets.
      [SIZE="1"]RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?[/SIZE]

      Kommentar


      • #4
        Lass die Hauptgruppen auf null zeigen, nicht auf sich selbst.

        - http://www.phpforum.de/forum/showthread.php?t=239679

        "Beispiel: Inhaltsverzeichnis" ist ein Ansatz für die Ausgabe.

        Kommentar


        • #5
          Ich habe den Ansatz von ChrisB gewählt: Nested Sets

          Hab mich auch schon weit durchgewühlt. Ich bin soweit das ich mir den Pfad zu einem Unterelement anzeigen lassen kann. Würde aber gern wissen ob ich das jetzt wirklich performant erledige oder ob das was ich mache zu viel ist..

          Erstmal meine neue Datenstruktur:

          Code:
          id | bezeichnung | lft | rgt | fachgebiet
          Fachgebiet ist in dem Fall ein foreign key auf die erste entity id. Dadurch kann ich mehrere Teilbäume in einer Tabelle verwalten. Das ist nötig da ich sonst nur eine Wurzel haben kann, was zu gewissen Nachteilen führt [...]

          Jetzt lese ich in einer Funktion einen Teilbaum aus (also den Pfad zum Teilbaum).
          Dazu hol ich mir zuerst die benötigten Entities mithilfe einer Abfrage, so das ich alle Werte
          für den Knoten habe, für das ich den Pfad suchen möchte:

          PHP-Code:
           //enthält die Werte für den Knoten, für welchen der Pfad zur Wurzel gesucht werden soll
          $node;

          //Sql-Abfrage - ermittelt den Weg zur Wurzel
          $result mysql_query(
             
          "SELECT n.id, n.bezeichnung, n.lft, n.rgt, COUNT(*)-1 AS lvl FROM ".
                
          "(SELECT * FROM $tablename WHERE fachgebiet=".$data['fachgebiet'].") AS n, ".
                
          "(SELECT * FROM $tablename WHERE fachgebiet=".$data['fachgebiet'].") AS o ".
             
          "WHERE n.lft BETWEEN o.lft AND o.rgt ".
               
               
          "AND n.lft <= ".$node['lft'] .
                   
               
          " AND (n.rgt + n.lft + (n.rgt - n.lft)) >= "
               
          .($data['rgt']+$data['lft'] + ($data['rgt']-$data['lft'])).
             
          " GROUP BY n.lft ".
             
          "ORDER BY n.lft "
          ); 
          Der "Trick" an der Sache ist, das ich mit der Formel:
          Code:
            lft + rgt + (rgt - lft)
          ermitteln kann ob ein Element eine Untermenge einer anderen Menge ist.
          Bei Bedarf kann ich noch ein paar Zeichnungen, Mengendarstellungen und Wertetabellen nachliefern, die ich während der Entwicklung erstellt hab.

          Gleichzeitig grenzt die Zeile:
          Code:
          AND n.lft <= ".$node['lft']
          alle Elemente aus die über dem gesuchten liegen.

          Ich habe Beispiele gesehen, die mit viel weniger Code angeblich dasselbe leisten können. Aber es war zum einen nicht nachvollziehbar, weshalb und zum anderen erhielt ich vollkommen unbrauchbare, bzw. unkorrekte Ergebnisse.

          Falls jemand in der Lage ist das ganze zu optimieren wäre ich überglücklich.

          Kommentar

          Lädt...
          X