#1 25. 4. 2009 18:14

murphy1
Člen
Registrovaný: 25. 4. 2009
Příspěvky: 1

Jak sestavit menu?

Dobrý den,
mám v MySQL databázi tabulku categories, která vypadá takto:

id name position parent
1 A 1 NULL
2 C 3 NULL
3 B 2 NULL
4 První A 1 1
5 První B 1 3
6 Druhá A 2 1
7 Třetí B 3 3
8 Druhá B 2 3
9 I 1 4
10 II 2 4
11 III 3 4

A potřebuji z ní udělat menu, seřazené podle sloupce position:

  • A
    • První A
      • I
      • II
      • III
    • Druhá A
  • B
    • První B
    • Druhá B
    • Třetí B
  • C

A úplně nejlepší by bylo, kdybych měl pohled (view) menu, který by vypadal takto:

id name depth
1 A 0
4 První A 1
9 I 2
10 II 2
11 III 2
6 Druhá A 1
3 B 0
5 První B 1
8 Druhá B 1
7 Třetí B 1
2 C 0

Offline

 

#2 25. 4. 2009 21:51

phx
Moderator
Místo: HK
Registrovaný: 17. 4. 2008
Příspěvky: 780
Web

Re: Jak sestavit menu?

Asi by bylo vhodnejsi zvolit jinou strukturu pro vychozi tabulku.

Doporucuji procist nasledujici odkazyk

Offline

 

#3 26. 4. 2009 9:01

Kevujin
Člen
Registrovaný: 6. 1. 2009
Příspěvky: 11

Re: Jak sestavit menu?

já bych řekl že tohle není špatná struktura. vytaháš si to rekurzivně (tj. pro každej uzel zavoláš dotaz). výsledek uložíš do cache (abys to netahal při každým dotazu), kterou budeš mazat jen při změně menu.

Offline

 

#4 26. 4. 2009 12:03

sodae
Nette Evangelist
Místo: Rád bych na pláži :)
Registrovaný: 8. 1. 2009
Příspěvky: 230
Web

Re: Jak sestavit menu?

Odskoušeno a funkční oproti munulé verzi co jsem to smazal :D sice jsem si už zvyk na dibi , ale něco jsem tu napsal :D fetchMenu() funkce vytahá z mysql menu , array( parent, childern ) 2. jej vypíše

function fetchMenu($parent = null){

        $menu = array();
        $q = mysql_query("select * from categories where parent='".$parent."' order by position")or die(mysql_error());
        while($f = mysql_fetch_array($q)){
                $menu[$f['id']] = array($f,fetchMenu($f['id']));
        }
        return $menu;
}

function echoMenu(array $menu,$sub=0){
  $priority = array();
  foreach($menu as $v){
    echo str_repeat('-',$sub).$v[0]['name']."<br>";
    echoMenu($v[1],$sub+1);
  }

}
echoMenu(fetchMenu());

Editoval sodae (26. 4. 2009 12:14)


Nette Jabber Room – nette@conf.netlab.cz , všichni jste vítání

Twitter: http://twitter.com/MartinSadovy

Offline

 

#5 27. 4. 2009 9:27

_Martin_
Člen
Místo: Praha
Registrovaný: 26. 9. 2008
Příspěvky: 543

Re: Jak sestavit menu?

sodae napsal(a):

function fetchMenu($parent = null){

        $menu = array();
        $q = mysql_query("select * from categories where parent='".$parent."' order by position")or die(mysql_error());
        while($f = mysql_fetch_array($q)){
                $menu[$f['id']] = array($f,fetchMenu($f['id']));
        }
        return $menu;
}

A nemůže se takový kód stát obrovským požíračem výkonu? Jen pro to ukázkové menu nahoře by se provedlo 12 dotazů do databáze (provede se vždy o jeden dotaz víc, než kolik položek menu má). Leda použít keš, s ní by to nemuselo vadit (pokud struktura nebude často aktualizována).

Offline

 

#6 27. 4. 2009 11:47

danaketh
Člen
Místo: Praha
Registrovaný: 27. 12. 2008
Příspěvky: 23
Web

Re: Jak sestavit menu?

Nebylo by lepší si hned na začátku vytáhnout celou strukturu do pole a pracovat pak s tím? Případně celou práci nechat na databázi…?


Saying that Java is nice because it works on all OS's is like saying that anal sex is nice because it works on all genders.

Offline

 

#7 27. 4. 2009 14:17

phx
Moderator
Místo: HK
Registrovaný: 17. 4. 2008
Příspěvky: 780
Web

Re: Jak sestavit menu?

MySQL nema moc podporu pro strom. Oracle tusim neco ma (dokaze spocitat deep).

Pokud chcete jedinim dotazem nacist strom z DB tak optimalni jsou ty metody co jsem odkazoval. Nevyhoda je pouze slozitejsi manipulace se stromem pri upravach, vkladani a vymazavani, ale selecty jsou relativne jednoduche.

Offline

 

#8 8. 5. 2009 11:16

cz106635
Člen
Registrovaný: 8. 5. 2009
Příspěvky: 1

Re: Jak sestavit menu?

to mutphy1: Když se budeš snažit načítat podkategorie po jedné v cyklu jak to píše sodae, tak rychle zjistíš, že tudy cesta nevede. Zbytečně zatěžuješ DB stroj. Pokud pak navrhneš robustnější aplikaci, kterou bude navštěvovat hodně lidí, tak zjistíš, že ti začne server padat na hubu.

Cesta je pouze pole např. http://www.quickpipe.com/…-menu-in-php (níže je uvedena složitější varianta, která je 100% funkční)

Jinak souhlasím s phx. Struktura DB by měla mít podobu http://dev.mysql.com/…al-data.html Je to geniálně jednoduché a přitom velmi rychlé. Pokud budeš dělat shop, tak se velmi rychle dá zjistit aktuální pozice, případně velmi rychle se dají vygenerovat cesty, mapy apod.

Offline

 

Zápatí