![]() |
|
|
Themen-Optionen |
|
|
Nach oben #1 | |
|
Erfahrener Benutzer
Registriert seit: 27.09.2006
Ort: Radebeul
Beiträge: 404
|
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 |
|
Erfahrener Benutzer
Registriert seit: 27.09.2006
Ort: Radebeul
Beiträge: 404
|
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 |
|
Erfahrener Benutzer
Registriert seit: 02.12.2004
Ort: Remagen
Beiträge: 4.616
|
Schon öfters verlinkt: http://reeg.junetz.de/DSP/node11.htm...00000000000000
Ist eigentlich ein tolles Tutorial (im Gesamten). |
|
|
|
|
|
Nach oben #7 |
|
Erfahrener Benutzer
Registriert seit: 02.12.2004
Ort: Remagen
Beiträge: 4.616
|
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: 274
|
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 | |
|
Erfahrener Benutzer
Registriert seit: 04.01.2006
Ort: Kassel
Beiträge: 774
|
Zitat:
Hier eine Umsetzung aus meinem Alltag: PHP-Code:
Basti |
|
|
|
|
|
|
Nach oben #10 |
|
Erfahrener Benutzer
Registriert seit: 30.10.2005
Beiträge: 274
|
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 | ||
|
Erfahrener Benutzer
Registriert seit: 04.01.2006
Ort: Kassel
Beiträge: 774
|
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 |
|
Erfahrener Benutzer
Registriert seit: 27.09.2006
Ort: Radebeul
Beiträge: 404
|
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 |
|
Erfahrener Benutzer
Registriert seit: 04.01.2006
Ort: Kassel
Beiträge: 774
|
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). |
|
|
|