Baumstruktur in Datenbank ablegen
der Hilker
- datenbank
0 Thomas0 hilker0 Thomas0 hilker
0 André Laugks
0 DANKE vergessen
Hallo erst mal,
nachdem ich schon seit einiger Zeit eine vernünftige Lösung für das im Subject beschriebene Problem suche, und so langsam "die Schnauze voll" habe wende ich mich mal an andere Leute die da evtl. auch schon Erfahrungen mit gemacht haben.
Bei meinem Projekt handelt es sich um ein Disskussionsforum wie dieses hier. Ich weiß auch das es jede Menge Forenscripts gibt, die ich einfach downloaden könnte aber entweder gefällt mir die Struktur von den Dingern nicht oder sie greifen nicht auf Datenbanken zurück sondern schreiben Files. Also fang ich selbst an ;-)
Etwas zur eingesetzen Software: Perl 5 + mySQL + Apache Webserver.
Ich hab grundsätzlich erstmal eine Tabelle "FORUM" erstellt mit folgenden cols ->
beitr_num,
beitr_vorg,
beitr_next,
mes_subject,
mes_body,
date,
time
nun fällt es mir doch recht schwer aus dieser Tabelle wieder eine Baunstruktur zu erstellen. Das größte Problem dabei ist, daß die Tabelle sich ja ständig verändert....
hat jemand einen Tip für mich? Muß ich 2 Tabellen anlegen und diese dann verbinden? ich hab keinen plan!
ich hoffe auf 'ne Antwort...
grüße Markus
Rekursion!!
Das Feld "beitr_next" kannst Du getrost vergessen.
Wichtig ist IMHO nur der Vorgänger. Und aus dem läßt sich die Position im Baum festlegen.
Z.B.
Nr---Vorgänger
1---
2---
3---2
4---1
5---2
6---3
7---6
Baum:
1
|--4
2
|--3
| |--6
| |--7
|--5
Thomas
Hallo erst mal,
nachdem ich schon seit einiger Zeit eine vernünftige Lösung für das im Subject beschriebene Problem suche, und so langsam "die Schnauze voll" habe wende ich mich mal an andere Leute die da evtl. auch schon Erfahrungen mit gemacht haben.
Bei meinem Projekt handelt es sich um ein Disskussionsforum wie dieses hier. Ich weiß auch das es jede Menge Forenscripts gibt, die ich einfach downloaden könnte aber entweder gefällt mir die Struktur von den Dingern nicht oder sie greifen nicht auf Datenbanken zurück sondern schreiben Files. Also fang ich selbst an ;-)
Etwas zur eingesetzen Software: Perl 5 + mySQL + Apache Webserver.
Ich hab grundsätzlich erstmal eine Tabelle "FORUM" erstellt mit folgenden cols ->
beitr_num,
beitr_vorg,
beitr_next,
mes_subject,
mes_body,
date,
time
nun fällt es mir doch recht schwer aus dieser Tabelle wieder eine Baunstruktur zu erstellen. Das größte Problem dabei ist, daß die Tabelle sich ja ständig verändert....
hat jemand einen Tip für mich? Muß ich 2 Tabellen anlegen und diese dann verbinden? ich hab keinen plan!
ich hoffe auf 'ne Antwort...
grüße Markus
Rekursion!!
ja das ich rekursiv vorgehen muß, bzw eine rekursive funktion benutzen muß, das dacht ich mir schon
Das Feld "beitr_next" kannst Du getrost vergessen.
OK
Wichtig ist IMHO nur der Vorgänger. Und aus dem läßt sich die Position im Baum festlegen.
Z.B.
Nr---Vorgänger
1---
2---
3---2
4---1
5---2
6---3
7---6
Baum:
1
|--4
2
|--3
| |--6
| |--7
|--5
Thomas
zu deinem Beispiel: genau so sieht's bei mir aus! aber um das als Baum auszugeben benötige ich imens viele DB-zugriffe...
ist ja klar die NULL felder entsprechen den ROOTS. aber auf welche weise kämpfe ich mich da nun durch um eine Sinnvolle Reihenfolge von "beitr_num" zu ermitteln?
Markus
zu deinem Beispiel: genau so sieht's bei mir aus! aber um das als Baum auszugeben benötige ich imens viele DB-zugriffe...
So ist das Leben...
ist ja klar die NULL felder entsprechen den ROOTS. aber auf welche weise kämpfe ich mich da nun durch um eine Sinnvolle Reihenfolge von "beitr_num" zu ermitteln?
Ob meine Lösung die sinnvollste ist, weiß ich nicht. Und die von Dir eingesetzten Technologien beherrsche ich nicht aber in der MS-Welt würde ich es mit ADO und VB etwa so lösen (Quick'n'Dirty):
Unter der Annahme, dass in den Root-Einträgen für den Vorgänger 0 (und nicht NULL) steht...
Start mit
BuildTree 0
sub BuildTree(Parent as long, Optional Step as Integer=0)
dim rs as new ADODB.Recordset
rs.open "SELECT num FROM tbl WHERE vorg =" & Parent, connection
do until rs.EOF
debug.print String(2*Step,"-") & rs!num
'Für jede Hierarchie-Stufe stellt die Fkt String 2 Bindestriche voran!
BuildTree rs!num, Step+1 'Rekursiver Aufruf!!!
rs.MoveNext
loop
rs.close
end sub
Hoffe, dass ich nix übersehen habe!
ich danke Dir...
aber dieses problem beschäftigt ja nicht nur mich ;-) soll ja noch ein paartausend andere geben die sich da einen kopf drum machen wie man sowas "elegant" lösen kann.
dann werd' ich wohl eine menge DB zugriffe in kauf nehmen müssen und drauf warten daß mir was besseres einfällt! ;-)
zu deinem Beispiel: genau so sieht's bei mir aus! aber um das als Baum auszugeben benötige ich imens viele DB-zugriffe...
So ist das Leben...
ist ja klar die NULL felder entsprechen den ROOTS. aber auf welche weise kämpfe ich mich da nun durch um eine Sinnvolle Reihenfolge von "beitr_num" zu ermitteln?
Ob meine Lösung die sinnvollste ist, weiß ich nicht. Und die von Dir eingesetzten Technologien beherrsche ich nicht aber in der MS-Welt würde ich es mit ADO und VB etwa so lösen (Quick'n'Dirty):
Unter der Annahme, dass in den Root-Einträgen für den Vorgänger 0 (und nicht NULL) steht...
Start mit
BuildTree 0
sub BuildTree(Parent as long, Optional Step as Integer=0)
dim rs as new ADODB.Recordset
rs.open "SELECT num FROM tbl WHERE vorg =" & Parent, connection
do until rs.EOF
debug.print String(2*Step,"-") & rs!num
'Für jede Hierarchie-Stufe stellt die Fkt String 2 Bindestriche voran!
BuildTree rs!num, Step+1 'Rekursiver Aufruf!!!
rs.MoveNext
loop
rs.close
end sub
Hoffe, dass ich nix übersehen habe!
Hallo!
zu deinem Beispiel: genau so sieht's bei mir aus! aber um das als Baum auszugeben benötige ich imens viele DB-zugriffe...
ist ja klar die NULL felder entsprechen den ROOTS. aber auf welche weise kämpfe ich mich da nun durch um eine Sinnvolle Reihenfolge von "beitr_num" zu ermitteln?
Da reicht ein Zugriff.
Die Beispiel hier habe ich für ein kleines Forum geschrieben http://www.readings.de/forum/forum.phtml.
Das ganze hier ist sehr einfach gestickt, der reguläre Ausdruck z.B., aber es funktioniert.
// Alle Datensätze mit NULL kommen in die Array $zeile_start_thread,
// der Rest in $zeile_antwort_thread.
while($db->fkt_fetch())
{
if(is_null($db->fetch["vornummer"])) // --> Anfangspostings
{
$zeile_start_thread[$db->fetch["id_forum"]] = array(
$db->fetch["id_forum"],
$db->fetch["betreff"],
$db->fetch["name"],
$db->fetch["datum"]);
}
else // --> Antwortpostings
{
$zeile_antwort_thread[$db->fetch["id_forum"]] = array(
$db->fetch["id_forum"],
$db->fetch["thread"],
$db->fetch["betreff"],
$db->fetch["name"],
$db->fetch["datum"],
$db->fetch["vornummer"],
$db->fetch["ebene"]);
}
}
// Dann die Arrays sortieren:
// absteigent
// IDs absteiget
array_multisort($zeile_start_thread, SORT_DESC);
// aufsteigent
// IDs aufstegent
array_multisort($zeile_antwort_thread, SORT_ASC);
// Nun schreibst Du die "Start-Postings" in ein Array.
$a = 0;
while(list($id, $inneres_array) = each($zeile_start_thread))
{
list($id, $betreff, $name, $datum) = $inneres_array;
$threads[$a] = "<ul><a href="beitrag.phtml?thread=" . $id . "&ebene=0&nr=". $id .""><b>" . $betreff . "</a></b> von " . $name . ", " . $datum;
$a++;
$threads[$a] = "</ul>";
$a++;
}
// Nun sortierst Du die Antworten ein:
$a = 0;
while(list($id, $inneres_array) = each($zeile_antwort_thread))
{
list($id, $thread, $betreff, $name, $datum, $vornummer, $ebene) = $inneres_array;
$suchmuster = "nr=" . $vornummer . "">";
for($i = 0; $i < count($threads); $i++)
{
$threads_neu[$a] = $threads[$i];
$a++;
if(ereg($suchmuster, $threads[$i]) == true)
{
$threads_neu[$a] = "<ul><a href="beitrag.phtml?thread=" . $thread . "&ebene=" . $ebene . "&nr=". $id ."">" . $betreff . "</a> von " . $name . ", " . $datum;
$a++;
$threads_neu[$a] = "</ul>";
$a++;
}
}
$a = 0;
$threads = $threads_neu;
}
Im Prinzip schiebst Du eine Antwort immer zwischen die Arrayelements. Du suchst im Array($thread) so lange, bist Du das Posting findest, von dem es die Antwort ist. Also 2 ist die Antwort auf 6. Ich suche also nach der 6 und schiebe die zwei rein und packe den Rest der Array($thread) dahinter. Die Array $neu_thread ist sozusagen eine temporäre Array, in der ich die neue ablege. Die neue lege ich dann wieder in der alten ab und es geht von vorne los.
Ich schreibe vorsorglich bestimmte sachen mit in die DB, wie die Postingebene. Ist für die Zukunft gedacht...
Es werden <ul></ul> verschatelt, daß ist nicht W3C konform!!!
MfG, André Laugks
hab ganz vergessen irgendwo DANKE zu schreiben.. sorry :o)
mfg hilker