Baum aus oracle dastellen

Johannes Schmidt

Grünschnabel
Hi,

Ich habe mit Hilfe von oracle (connect by) eine Baumstruktur aus einer meiner Datenbank ausgelesen und würde diese nun gerne möglichst Resourcenschonend in einer Listenstruktur ausgeben.

Die Daten kommen wie folgt aus der Datenbank:

Code:
ID  PARENT  LEVEL NAME
1   NULL       1          root
2   1             2          subA
3   1             2          subB
4   3             3          subB1
5   3             3          subB2

Ich würde daraus nun gerne folgendes erzeugen:

HTML:
<ul>
  <li id="1">root<ul>
    <li id="2">subA</li>
    <li id="3">subB<ul>
      <li id="4">subB1</li>
      <li id="5">subB2</li>
    </ul></li>
  </ul></li>
</ul>

Wie würdet ihr das machen um das ganze auch bei ca. 2000 Datensätzen performant zu halten?

Viele Grüße
 
Hi, also ich würde gerade bei grossen Datenmengen empfehlen das Nested Sets Modell zur Speicherung der Daten in der Datenbank zu verwenden, da man dann die Daten bereits fertig sortiert beim auslesen erhält, und so nicht umsortieren muss für die Ausgabe. Das ganze lohnt sich allerdings hauptsächlich dann, wenn man mehr Lese- als Schreibzugriffe auf die Daten hat.

Falls du beim von dir gewählten Modell bleibst, ist der Aufwand beim Auslesen der Daten grösser, ich würde in diesem Fall empfehlen, die Datensätze in der SQL-Abfrage aufsteigend nach Level sortieren zu lassen und beim auslesen in einem Array zu speichern, indem du die ID als Schlüssel verwendest, die anderen Daten entsprechend übernimmst und zusätzlich ein Array für die untergeordneten Elemente anlegst, also etwa so:
PHP:
$nodes = array();

$nodes[1] = array
(
  'level' => 1,
  'name' => 'root',
  'childs' => array
  (
    2,
    3
  )
);

...

$nodes[3] = array
(
  'level' => 2,
  'name' => 'subB',
  'childs' => array
  (
    4,
    5
  )
);

...
Für die Ausgabe fängst du dann beim Wurzelknoten (1) an, gibst die Daten aus und weisst dann durch das "childs"-Array, welche Knoten du als untergeordnete Elemente ausgeben musst. Zur Ausgabe würde ich definitiv eine rekursive Funktion empfehlen, wie es bei Baumstrukturen meistens üblich ist. Diese Funktion müsste die Ausgabe des aktuellen Knotens übernehmen und sich dann selbst aufrufen, für jeden Kindknoten.

Hoffe das hilft weiter.

EDIT: Mir ist gerade noch folgendes aufgefallen: wenn die Daten so im Array speicherst, wie ich es vorgeschlagen habe, kannst du im Prinzip auch auf die "level"-Information verzichten, das die Funktion zur Ausgabe das übernehmen kann, allerdings nur wenn der Startwert feststeht, also bei Ausgabe des ganzen Baums: 1
 
Zuletzt bearbeitet:
Hi,

Danke. Die Idee mit dem sortieren nach Level wäre auch mein Ansatz gewesen. Dann werde ich das so mal umsetzen - der Ansatz direkt von Oracle ist zwar auch nicht schlecht:
http://www.oracle.com/technology/pub/articles/oracle_php_cookbook/bollweg_easytrees.html
nimmt mir aber etwas die flexibilität in Bezug auf die Darstellung.

@nested sets: Im Vergleich zu der oracle eigenen Funktion "connect by" sind nested stets deutlich aufwändiger in Bezug auf die Programm Logik und der Aufwand auf Seiten der Datenbank ist auch höher - allerdings zählt das wie gesagt nur für oracle. Andere Datenbanken unterstützen diese spezielle Funktion zum auslesen von bäumen nicht.

Danke
 
Hi,

so ich hab mich jetzt doch für die von Oracle vorgeschlagene Variante entschlossen. Wenn man diese richtig anwendet, dann enfällt jede recursive Schleife - das macht den Aufbau der Struktur richtig schnell.

... da die Klasse, die ich dazu geschrieben habe an die 1000 Zeilen code hat poste ich das jetzt mal nicht :rolleyes: das oben verlinkte Beispiel von Oracle enthällt sowieso die besseren Erklärungen :)

Danke
 
Zurück