[PHP] Probleme mit Nested Sets

resoucer

Gesperrt
ID: 77379
L
20 April 2006
2.846
109
Hallo,

ich habe ein kleines Problem.
Undzwar habe ich eine CSV datei mit vielen Einträgen (u.A. die Spalte "Kategorie")
die Spalte Kategorie ist wie folgt aufgebaut "Fernseher ab 70cm > 50 Hz > schwarz"

Sprich
1. Hauptkategorie (wir von mir vorgegeben): Test
2. Kategorie: Fernseher ab 70cm
3. Kategorie: 50 Hz
4. Kategorie: schwarz

Jetzt muss ich, wenn ich mit Nested Sets arbeite ja die Anzahl der Kategorien im voraus wissen. D.h. ich muss den kompletten Inhalt der csv auslesen, kategorien zählen und irgendwie zwischenspeichern. Diesen Kategorien dann einen zahlenraum zuweisen und speichern.
Dann lese ich die csv nochmal aus und ordne die kategorien den Artikeln zu. (kompliziert! :yawn: )

Mir kommt das aber ein wenig zu "falsch" vor. Evtl. hat einer ne Idee wie man die Sache besser angehen kann, da das o.g. Prozedere nicht sehr einfach ist zu realisieren.
 
du musst die anzahl nicht kennen.
neue kategorien werden einfach eingefügt in dem teil der teil links/rechts mit nem +1 oder -1 bearbeitet wird (wenn ich mich recht entsinne).
und dann einfach mit der richtigen right left eintragen

aber vorraus zählen muss definitv nicht sein, könnte man natürlich aber aus performance-gründen machen, dass man die struktur gleich so im php vorbereitet.
 
ich habe jetzt mal nen kleinen test gemacht

Folgende DB Struktur:
Code:
CREATE TABLE IF NOT EXISTS `zwischenspeicher2` (
  `id` int(11) NOT NULL auto_increment,
  `name` varchar(50) NOT NULL,
  `links` int(11) NOT NULL,
  `rechts` int(11) NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=11 ;

INSERT INTO `zwischenspeicher2` (`id`, `name`, `links`, `rechts`) VALUES
(1, 'Test', 1, 18),
(2, 'All-In-One Drucker', 2, 3),
(3, 'Fernseher ab 70cm', 4, 7),
(4, 'Rasierer', 6, 9),
(5, 'Sonstige TV', 8, 11),
(6, 'Sonstige Wohn/Büro/Kleinmöbel/Badartikel', 10, 11),
(7, 'Tische', 12, 13),
(8, '50 Hz', 5, 6),
(9, 'DVD', 9, 10),
(10, 'Ladyshaver', 7, 8);
Ich denke die Kategorien stimmen, oder?
So sind die org.
Code:
All-In-One Drucker
Sonstige Wohn/Büro/Kleinmöbel/Badartikel
Rasierer > Ladyshaver
Tische
Sonstige TV > DVD > VHS
Fernseher ab 70cm > 50 Hz > 100 Hz

Jetzt will ich mit diesem Code die Ebenen ausgeben.
PHP:
SELECT n.name, COUNT( * ) -1 AS ebene
FROM zwischenspeicher2 AS n, zwischenspeicher2 AS p
WHERE n.links
BETWEEN p.links
AND p.rechts
GROUP BY n.links
ORDER BY n.links;

Ergebnis

123bfa44968jpg.jpg

Klappt also irgendwie nicht 100%ig, da z.B. "Sonstige TV" / "Sonstige Wohn/Büro/Kleinmöbel/Badartikel" auch Ebene 1 ist.
Aber ich weis nicht genau wo der Fehler liegt.
 
ich habe jetzt mal nen kleinen test gemacht
INSERT INTO `zwischenspeicher2` (`id`, `name`, `links`, `rechts`) VALUES
(1, 'Test', 1, 18),
(2, 'All-In-One Drucker', 2, 3),
(3, 'Fernseher ab 70cm', 4, 7),
(4, 'Rasierer', 6, 9),
(5, 'Sonstige TV', 8, 11),
(6, 'Sonstige Wohn/Büro/Kleinmöbel/Badartikel', 10, 11),
(7, 'Tische', 12, 13),
(8, '50 Hz', 5, 6),
(9, 'DVD', 9, 10),
(10, 'Ladyshaver', 7, 8);
[/code]
Ich denke die Kategorien stimmen, oder?
Nee, die Kategorien stimmen nicht.
Fernseher ist bei dir 4,7 und Rasierer 6,9. Das passt hinten und vorne nicht. Rasierer wäre damit eine fehlerhafte Teilmenge der Fernseher ;)

So sind die org.
Code:
All-In-One Drucker
Sonstige Wohn/Büro/Kleinmöbel/Badartikel
Rasierer > Ladyshaver
Tische
Sonstige TV > DVD > VHS
Fernseher ab 70cm > 50 Hz > 100 Hz

Die Kategorien müssen folgende Links und Rechts-Werte haben:
Test L:1 R:23
All-In-One Drucker L:2 R:3
Sonstige Wohn/Büro/Kleinmöbel/Badartikel L:3 R:4
Rasierer L:5 R:8
Ladyshaver L:6 R:7
Tische L:9: R:10
Sonstige TV L:11 R:16
DVD L:12 R:13
VHS L:14 R:15
Fernseher ab 70cm L:17 R:22
50 Hz L:18 R:19
100 Hz L:20 R:21

Am besten malt man sich sowas auf und schreibt dann in der Reihenfolge, in der der Baum abgelaufen werden soll, die Ziffern ran.
 
So jetzt habe ich wieder ein kleines Problem welches nicht einkalkuliert war.

Undzwar habe ich eine Tabelle wo ich alle Kategorien der csv speichern

PHP:
CREATE TABLE IF NOT EXISTS `zwischenspeicher` (
  `id` int(11) NOT NULL auto_increment,
  `k1` varchar(100) NOT NULL,
  `k2` varchar(100) NOT NULL,
  `k3` varchar(100) NOT NULL,
  `k4` varchar(100) NOT NULL,
  `k5` varchar(100) NOT NULL,
  `k6` varchar(100) NOT NULL,
  `k7` varchar(100) NOT NULL,
  `k8` varchar(100) NOT NULL,
  `k9` varchar(100) NOT NULL,
  `artnr` varchar(50) NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=33 ;
Klappt alles wunderbar.
Jetzt lege ich die Kategorien mit rechts / links an

PHP:
CREATE TABLE IF NOT EXISTS `kategorien` (
  `id` int(11) NOT NULL auto_increment,
  `name` varchar(50) NOT NULL,
  `links` int(11) NOT NULL,
  `rechts` int(11) NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=11 ;

Jetzt rechne ich den Linken und Rechten bereich aus

PHP:
 $von1 =mysql_query("SELECT links,rechts from kategorien order by rechts desc LIMIT 1"); $von1=mysql_fetch_array($von1);
    
     $von = $von1['rechts']+1;$bis=$von1['rechts']+2;
     $tb = mysql_query("SELECT * From zwischenspeicher group by k1 order by k1 asc");
     while($row=mysql_fetch_array($tb)) {  
     	
    	mysql_query("INSERT into `kategorien` (name,links,rechts) VALUES ('".$row['k1']."',$von,$bis)");
    	
     }
    
     $tb = mysql_query("SELECT * From zwischenspeicher where `k2` !='' group by k2 order by k2 asc");
     while($row=mysql_fetch_array($tb)) {  
        $von++;	$bis++;	  	
    	mysql_query("UPDATE kategorien set rechts=rechts+2 where rechts >= $von");

    	mysql_query("INSERT into `kategorien` (name,links,rechts) VALUES ('".$row['k2']."',$von,$bis)");    	

    	$von++;	$bis++;
     }
     
       $tb = mysql_query("SELECT * From zwischenspeicher where `k3` !='' group by k3 order by k3 asc");
     while($row=mysql_fetch_array($tb)) {  
        $von++;	$bis++;	
        $row2 =mysql_query("SELECT links,rechts from kategorien where name='".$row['k2']."'"); $row2=mysql_fetch_array($row2);
   	
    	mysql_query("UPDATE kategorien set rechts=rechts+2 where rechts >= ".$row2['rechts']."");
    	mysql_query("UPDATE kategorien set links=links+2 where links >= ".$row2['rechts']."");
    	mysql_query("INSERT into `kategorien` (name,links,rechts) VALUES ('".$row['k3']."',".($row2['links']+1).",".($row2['links']+2).")");    	
    	echo mysql_error();
    	$von++;	$bis++;
     }
     
     $a=1;
       $tb = mysql_query("SELECT * From zwischenspeicher where `k4` !='' group by k4 order by k4 asc");
     while($row=mysql_fetch_array($tb)) {  
        $von++;	$bis++;	
        $row2 =mysql_query("SELECT links,rechts from kategorien where name='".$row['k3']."'"); $row2=mysql_fetch_array($row2);       
 	
    	mysql_query("UPDATE kategorien set rechts=rechts+2 where rechts >= ".$row2['rechts']."");
    	mysql_query("UPDATE kategorien set links=links+2 where links >= ".$row2['rechts']."");
    
    	mysql_query("INSERT into `kategorien` (name,links,rechts) VALUES ('".$row['k4']."',".($row2['links']+$a).",".($row2['links']+$a + 1).")");    	
    	$von++;	$bis++;
    	$a +=2;
     }
     
        $tb = mysql_query("SELECT * From zwischenspeicher where `k5` !='' group by k5 order by k5 asc");
     while($row=mysql_fetch_array($tb)) {  
        $von++;	$bis++;	
        $row2 =mysql_query("SELECT links,rechts from kategorien where name='".$row['k4']."'"); $row2=mysql_fetch_array($row2);
    	echo "(".$row['k4'].")UPDATE kategorien set rechts=rechts+2 where rechts >= ".$row2['rechts']."";    	
    	mysql_query("UPDATE kategorien set rechts=rechts+2 where rechts >= ".$row2['rechts']."");
    	mysql_query("UPDATE kategorien set links=links+2 where links >= ".$row2['rechts']."");
    
    	mysql_query("INSERT into `kategorien` (name,links,rechts) VALUES ('".$row['k5']."',".($row2['links']+$a).",".($row2['links']+$a + 1).")");    	
    	echo mysql_error();
    	$von++;	$bis++;
    	$a +=2;
     }
Das Problem ist ist dieser Teil
PHP:
SELECT links,rechts from kategorien where name='".$row['k4']."'"
k2 / k3 / k4 (weitere kategorien habe ich jetzt hier noch nicht drin)
Undzwar habe ich jetzt den Fall das eine Kategorie den Namen "D - I" hat und eine Kategorie den selben Namen (aber eine andere Oberkategorie).
Dann klappt die Zuordnung nicht mehr ganz!

Als Beispielkategorien habe ich folgende genommen
PHP:
Fantasy > Bücher > Bücher nach Autoren > T - Z > Tolkien, J. R. R.
Fantasy > Bücher > Bücher nach Autoren > T - Z > Tolkien, J. R. R.
Fantasy > Bücher > Bücher nach Autoren > T - Z > Tolkien, J. R. R.
Fantasy > Bücher > Bücher nach Autoren > T - Z > Tolkien, J. R. R.
Fantasy > Bücher > Bücher nach Autoren > A - C > Carpenter, Humphrey
Fantasy > Bücher > Bücher nach Autoren > J - O > Krege, Wolfgang
Fantasy > Bücher > Bücher nach Autoren > J - O > Murray, Andrew
Fantasy > Bücher > Bücher nach Autoren > P - S > Strachey, Barbara
Fantasy > Bücher > Bücher nach Autoren > D - I > Fonstad, Karen Wynn
Fantasy > Bücher > Bücher nach Autoren > T - Z > Tolkien, J. R. R.
Fantasy > Bücher > Bücher nach Autoren > T - Z > Tolkien, J. R. R.
Fantasy > Bücher > Bücher nach Autoren > T - Z > Tolkien, J. R. R.
Fantasy > Bücher > Bücher nach Autoren > T - Z > Tolkien, J. R. R.
Fantasy > Bücher > Bücher nach Autoren > T - Z > Tolkien, J. R. R.
Fantasy > Bücher > Bücher nach Autoren > T - Z > Tolkien, J. R. R.
Fantasy > Bücher > Bücher nach Autoren > T - Z > Tolkien, J. R. R.
Fantasy > Bücher > Bücher nach Autoren > T - Z > Tolkien, J. R. R.
Fantasy > Bücher > Bücher nach Autoren > T - Z > Tolkien, J. R. R.
Fantasy > Bücher > Bücher nach Autoren > T - Z > Tolkien, J. R. R.
Fantasy > Bücher > Bücher nach Autoren > T - Z > Tolkien, J. R. R.
Fantasy > Bücher > Bücher nach Autoren > D - I > Hammond, Wayne G.
Fantasy > Bücher > Bücher nach Autoren > T - Z > Tolkien, J. R. R.
Fantasy > Bücher > Fantasybände & Zyklen > D - I > Der Herr der Ringe
Fantasy > Bücher > Fantasybände & Zyklen > D - I > Der Herr der Ringe
Fantasy > Bücher > Fantasybände & Zyklen > D - I > Der Herr der Ringe
Fantasy > Bücher > Bücher nach Autoren > D - I > Fisher, Jude
Fantasy > Bücher > Bücher nach Autoren > T - Z > Tolkien, J. R. R.
Fantasy > Bücher > Bücher nach Autoren > T - Z > Tolkien, J. R. R.
Fantasy > Bücher > Bücher nach Autoren > P - S > Shippey, Tom
Fantasy > Bücher > Bücher nach Autoren > J - O > Krege, Wolfgang
Fantasy > Bücher > Bücher nach Autoren > T - Z > Tolkien, J. R. R.
Fantasy > Bücher > Bücher nach Autoren > A - C > Bidlo, Oliver D.

Da gibt es ja die Kategorie D - I mit der Oberkategorie "Fantasybände & Zyklen" und einmal mit der Oberkategorie "Bücher nach Autoren"


Vielleicht kann mir da einer einen kleinen Tipp geben wie man das (besser) lösen kann :roll: