![]() |
| | Themen-Optionen |
| | Nach oben #1 | |
| Gabriel Registriert seit: 27.09.2006 Ort: Radebeul
Beiträge: 406
|
Hei ho, ich bin mal wieder dabei eine Breadcrumb Navigation zu erstellen. Diese Soll diesesmal allerdings unendlich weit nachu nten gefächert werden können. Also hab ich nochmal in meinem alten Beitrag gelesen (Umsetzung einer Breadcrumb Navigation mit PHP/MySQL) und bin auf Nested Sets gekommen. Also mal angeschaut und versucht umzusetzen. Dabei bin ich bei diesem Tutorial gelandet: http://www.klempert.de/nested_sets/artikel/ Und da gibt es ein SQL-Statement: Code: CREATE TABLE tree (
id INT(12) UNSIGNED NOT NULL AUTO_INCREMENT,
name VARCHAR(50) NOT NULL,
lft INT(12) UNSIGNED NOT NULL,
rgt INT(12) UNSIGNED NOT NULL,
PRIMARY KEY (id),
key lft (lft),
key rgt (rgt),
);
Zitat:
| |
| | |
| | Nach oben #3 |
| Gabriel Registriert seit: 27.09.2006 Ort: Radebeul
Beiträge: 406
|
Oha, ich hab immer nur auf die Grafik mit dem "X" geschaut und die war an der Zeile mit der aussage: Code: rgt INT(12) UNSIGNED NOT NULL, Danke, jetzt kann ich weiterlesen. Ich werd sicher noch die eine oder andere Frage zu Nested Sets stellen. Bin nich so Fit in SQL |
| | |
| | Nach oben #4 |
| Benjamin Klaile Registriert seit: 02.12.2004 Ort: Remagen
Beiträge: 4.480
|
Schon öfters verlinkt: http://reeg.junetz.de/DSP/node11.htm...00000000000000 Ist eigentlich ein tolles Tutorial (im Gesamten). |
| | |
| | Nach oben #7 |
| Benjamin Klaile Registriert seit: 02.12.2004 Ort: Remagen
Beiträge: 4.480
|
Irgendwie passt es und passt gleichzeitig nicht ... egal: *spam* Neusortieren / Neuordnen von NestedSets mit PHP und JavaScript http://www.dotvoid.com/view.php?id=78 |
| | |
| | Nach oben #8 |
| Erfahrener Benutzer Registriert seit: 30.10.2005
Beiträge: 279
|
Auf der PHP Perfomance Page sowie bei der Seite von Arne Klempert ist folgender Query, nötig wenn Kategorien gelöscht werden: DELETE FROM kategorien WHERE lft BETWEEN $LFT AND $RGT; Danach kommt noch: UPDATE kategorien SET lft=lft-1, rgt=rgt-1 WHERE lft BETWEEN $LFT AND $RGT; UPDATE kategorien SET lft=lft-2 WHERE lft>$RGT; UPDATE kategorien SET rgt=rgt-2 WHERE rgt>$RGT; Mit diesen vier Queries soll erzielt werden das eine Kategorie gelöscht wird und die darunterliegenden auf die Ebene der gelöschten Kategorie kommen. Allerdings funktioniert das bei mir nicht da der DELETE Query ja die darunterliegenden Kategorien sofort killt. Ich hab den DELETE Query geändert und dadurch scheint es zu funktionieren: DELETE FROM kategorien WHERE lft = $LFT AND rgt = $RGT; Versteht das einer? Oder muss es wirklich BETWEEN heißen? Außerdem hat jemand noch einen Ansatz wie ich Kategorien verschiebe? |
| | |
| | Nach oben #9 | |
| Bastian Fenske Registriert seit: 04.01.2006 Ort: Kassel
Beiträge: 826
| Zitat:
Hier eine Umsetzung aus meinem Alltag: PHP-Code: Basti | |
| | |
| | Nach oben #10 |
| Erfahrener Benutzer Registriert seit: 30.10.2005
Beiträge: 279
|
Hi Basti. Ich hab dein Code mal ausprobiert und bei mir wird der jeweilige Knoten (und die darunterliegenden gelöscht) wie es sein soll. Hast du noch ein paar andere Ansätze? Ich versuche eben allgemein Grade mir eine Schnittstelle für sowas zu bauen, wo man die Kategorien so hin und herschieben, kann wie die Überschriften im Navigator von OpenOffice. Ach Basti, dein Code ist recht simple, hast du das geschrieben? Das bin ich garnicht gewohnt von deinen Posts. Normalerweise sind die immer so kompliziert. |
| | |
| | Nach oben #11 | ||
| Bastian Fenske Registriert seit: 04.01.2006 Ort: Kassel
Beiträge: 826
| Zitat:
PHP-Code: Zitat:
Basti PS: In der Regel wird es geschickter sein, die Knoten mit ihren Rechts- und Links-Werten in Objekten zu speichern. In meinem Kontext hier war das aber nicht sinnig, daher muss ich immer erst die Werte auslesen. Geändert von Basti (15.09.2007 um 11:42 Uhr). | ||
| | |
| | Nach oben #12 |
| Gabriel Registriert seit: 27.09.2006 Ort: Radebeul
Beiträge: 406
|
Hallo, bei der Umsetzung des Nested-Sets in PHP code hab ich ein Problem. Wenn cih jetzt ein erstes Kind des Root-Punktes Setzen möchte dann mach cih das mit folgendem Code: PHP-Code: Es ensteht dann Folgende konstruktion: PHP-Code: PHP-Code: Was muss ich an meinem SQL-Statement ändern? |
| | |
| | Nach oben #13 |
| Bastian Fenske Registriert seit: 04.01.2006 Ort: Kassel
Beiträge: 826
|
Was machst du? Du fragst nach dem rechten Wert des Root-Knotens. Dann erhöhst du alle Knoten, deren rechter Knoten größer oder gleich diesem rechten Root-Knoten-Wert ist. Größer gibt es nicht, da der rechte Root-Knoten-Wert ja bereits der größte Wert ist, also wird nur der rechte Wert des Root-Knotens um zwei vergrößert. In die entstandene Lücke packst du nun den neuen Knoten rein. Die Funktion müsste also genaugenommen appendRootChild() oder so heißen. Wenn du Nagetiere als Unterknoten von Primat definieren magst (warum auch immer), dann musst du Primat als Bezugspunkt angeben und anstatt getRoot() eben eine Funktion getNode() benutzen. Dann allerdings musst du auch alle Links-Werte die größer als dem alten rechten Wert des Bezugsknotens sind um zwei hochzählen (oder wie groß der Teilbaum auch immer sei, falls mal ein Teilbaum eingebunden werden soll). - Bestehender Baum sei TreeA, einzufügender Baum sei TreeB. - Der Knoten in TreeA, an den TreeB als Kind angehängt werden soll, sei NodeP - Neuen Baum ausmessen: Wie breit ist der Baum der eingefügt werden soll? Rechter minus linker Wert des Wurzelknotens des neuen Baumes: TreeB.width = TreeB.getRoot().right - TreeB.getRoot().left + 1 - NodeP.right sei r Das ist der jetzige rechte Wert des Eltern-Knotens. Da sich dieser ändern wird, macht es Sinn, diesen in eine Variable zu kopieren. - Platz machen: Damit der neue Baum reinpasst müssen nun alle Werte ab einem bestimmten Wert um die Breite des einzufügenden Baumes hochgezählt werden. Dieser bestimmte Wert ist r, der jetzige rechte Wert des Eltern-Knotens. Nimm also alle left- und right-Werte in TreeA, die größer oder gleich r sind und erhöhe sie um TreeB.width. - TreeB.getRoot().left muss auf r und alls anderen Werte in TreeB entsprechend hochgezählt werden. Die Differenz ist also r - TreeB.getRoot().left. Zu jedem Wert in TreeB addierst du nun also diesen Wert. - Jetzt schiebst du die Daten von TreeB noch in TreeA rein und fertig. Beispiel: Code: Baum A: A.a 1 8 A.b 2 5 A.c 3 4 A.d 6 7 Baum B: B.1 1 6 B.2 2 5 B.3 3 4 B soll als Kind von A.b eingefügt werden: B.width = B.1.right - B.1.left + 1 (=6) r = A.b.right (=5) UPDATE A SET right = right + B.width WHERE right => r UPDATE A SET left = left + B.width WHERE left > r (gleich gibts ja nicht) Jetzt sieht a so aus: A.a 1 14 A.b 2 11 A.c 3 4 A.d 12 13 B-Werte um 4 hochzählen (A.b.right - B.1.left, also 5 - 1:( B.1 5 10 B.2 6 9 B.3 7 8 Passt genau rein: A.a 1 14 A.b 2 11 A.c 3 4 B.1 5 10 B.2 6 9 B.3 7 8 A.d 12 13 - r = parent.right - rechts = rechts + 2 wo rechts >= r - links = links +2 wo links > r - Knoten einfügen mit left = r und right = r+1 Also eben genau dein Code, nur mit parent anstatt root, falls nicht root der Bezugsknoten sein soll. Basti Geändert von Basti (16.09.2007 um 00:01 Uhr). |
| | |
| | Nach oben #14 |
| Gabriel Registriert seit: 27.09.2006 Ort: Radebeul
Beiträge: 406
|
Danke Basti, dein Post muss ich jetzt erstmal solange durchlesen bis ich alles verstanden habe... Allerdings, ich wollte Nageitere nicht als Unterpunkt von Primaten einfügen sondern als Unterpunkt von Säugetiere. Letztend endes sollte dann sowas rauskommen: ![]() Quelle: http://www.klempert.de/nested_sets/artikel/#abb3 Jetzt werd ich erstmal deinen Post auseinander nehmen |
| | |
| | Nach oben #15 |
| Erfahrener Benutzer Registriert seit: 30.10.2005
Beiträge: 279
|
Der untere Query gibt mir den Baum komplett aus. Allerdings nicht sortiert nach Name (als für jeden Ast von A-Z). Etwas an das Order By zu hängen hilft auch nichts. PHP-Code: Dachte mir ich könnte auf $ebenen ein array_multisort machen, aber ich wie ich das dafür einsetze und ob es an der Stelle überhaupt geschickt ist weiß ich nicht. PHP-Code: |
| | |
| | Nach oben #16 | |
| Bastian Fenske Registriert seit: 04.01.2006 Ort: Kassel
Beiträge: 826
| Zitat:
Säugetiere 1 6 // Root Primaten 2 3 Nagetiere 4 5 Hier sind "Primaten" und "Nagetiere" direkte Kinder von "Säugetiere". "Nagetiere" ist rechter Geschwisterknoten von "Primaten". @"ex2": Nach welchem Wert willst du denn sortieren? Basti | |
| | |
| | Nach oben #18 |
| Erfahrener Benutzer Registriert seit: 30.10.2005
Beiträge: 279
|
Derzeit werden die ganzen Knoten glaube ich von links nach rechts aufgelistet (ORDER BY left) Demnach wird der Wurzelknoten ganz oben gelistet da er ja 1 hat. Ich hatte aber vor das nach Namen jedes Knotens zu sortieren. Also die Hierachie soll schon beibehalten werden, allerdings auf jedem Knoten soll dies nach Namen sortiert werden ungefähr so: Code: Exotisches Mango Papaya Ananas Aus der Heimat Birne Apfel Code: Aus der Heimat Apfel Birne Exotisches Ananas Mango Papaya |
| | |
| | Nach oben #19 |
| Benjamin Klaile Registriert seit: 02.12.2004 Ort: Remagen
Beiträge: 4.480
|
Ich hau hier einfach noch einen Blogeintrag rein: http://ishouldbecoding.com/2007/09/1...cal-data-sets/ |
| |