Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: schemat bazy danych dla wielopoziomowego menu
Forum PHP.pl > Forum > Bazy danych
Birkoff
Mam następujący problem:

Chcę użyc w serwisie wielopoziomowe menu - mam już odpowiedni skrypt java script / DHTML, ale największym problemem jest przechowywanie zawartości menu w bazie danych. Jaką stworzyć strukturę menu by byz problemu moż dodawać i zarządzać 3 lub 4 poziomami menu?

Probowalem już różnych własnych rozwiązań, ale nie mam pomysłu na coś naprawdę uniwersalnego.

Jeśli znacie jakieś gotowe struktury (mogą być z jakiegoś CMSa, obojętnie) lub macie choć dobry pomysł jak coś takiego zrealizować, to bardzo proszę o posty w tym temacie.

Z góry dziękuję!

Pozdrawiam!
dr_bonzo
szukaj: "drzewka sql", jest topic na forum (chyba przez rzseattle)
Birkoff
Cytat(dr_bonzo @ 2006-02-17 13:33:53)
szukaj: "drzewka sql", jest topic na forum (chyba przez rzseattle)

Dzieki - pomoglo smile.gif

Jak sie okazuje temat bardzo ciekawy smile.gif
Jako, że może się to komuś przydać to przedstawie rozwiązanie jakie zastosowalem...

Ponieważ generuję tylko menu (a więc relatywnie małą ilość danych) postanowiłem wykorzystać rekurencję.

Na początek baza danych:

  1. CREATE TABLE `menu` (
  2. `id` tinyint(3) NOT NULL AUTO_INCREMENT,
  3. `parent_id` tinyint(3) NOT NULL DEFAULT '0',
  4. `name` varchar(255) NOT NULL DEFAULT '',
  5. PRIMARY KEY (`id`)
  6. ) TYPE=MyISAM AUTO_INCREMENT=11 ;
  7.  
  8. INSERT
  9. INTO `menu`
  10. VALUES (1, 0, 'main_menu');
  11. INSERT
  12. INTO `menu`
  13. VALUES (2, 1, 'O firmie');
  14. INSERT
  15. INTO `menu`
  16. VALUES (3, 2, 'Nasza historia');
  17. INSERT
  18. INTO `menu`
  19. VALUES (4, 2, 'Nasze plany');
  20. INSERT
  21. INTO `menu`
  22. VALUES (5, 1, 'Produkty');
  23. INSERT
  24. INTO `menu`
  25. VALUES (6, 1, 'Download');
  26. INSERT
  27. INTO `menu`
  28. VALUES (7, 4, 'Pozniejsze plany');
  29. INSERT
  30. INTO `menu`
  31. VALUES (8, 7, 'A w odleglej przyszlosci...');
  32. INSERT
  33. INTO `menu`
  34. VALUES (9, 8, 'W odleglej galaktyce...');
  35. INSERT
  36. INTO `menu`
  37. VALUES (10, 3, 'podmenu :)');


Jak widać wykorzystałem pole parent_id do określenia rodzica dla danej pozycji.

Oto funkcja rekurencyjna generująca menu:

  1. <?php
  2. function generate_menu($parentid)
  3. {
  4. $rs = db_query("SELECT * FROM menu WHERE parent_id = ".$parentid." ");
  5. $count = db_num_rows ($rs);
  6. if ( $count > 0 )
  7. {
  8. while ( $row = db_fetch_assoc($rs) )
  9. {
  10.  
  11. $menu .= '<li><a href="#">'.$row['name'].'</a>';
  12.  
  13. $rs1 = db_query("SELECT * FROM menu WHERE parent_id = ".$row['id']." ");
  14. $count1 = db_num_rows ($rs1);
  15. if ( $count1 > 0 )
  16. {
  17. $menu .= "<ul>";
  18. $menu .= generate_menu($row['id']);
  19. $menu .= "</ul>";
  20. }
  21.  
  22. $menu .= '</li>';
  23.  
  24. }
  25. }
  26. return( $menu );
  27. }
  28. ?>



Kod jest specyficzny, bo muszę wygenerować specyficzny układ tagów <ul> i <li>, który to jest potem interpretowany przez skrypt JS wyświetlający menu.

Oto wywołanie generujące menu:

  1. <?php
  2. $menu='<ul id="udm" class="udm">'.generate_menu(1).'</ul>';
  3. ?>


Jak widać można wygenerować jedno lub kilka menu - w zależności który parent_id podamy jako argument funkcji... Poziom root dla danego menu tworzy element z parent_id = 0.

Oto wygenerowany kod:

Kod
<ul id="udm" class="udm">
    <li><a href="#">O firmie</a>
    <ul>
  <li><a href="#">Nasza historia</a>
  <ul>
      <li><a href="#">podmenu :)</a></li>
  </ul>
  </li>
  <li><a href="#">Nasze plany</a>
  <ul>
      <li><a href="#">Pozniejsze plany</a>
      <ul>
    <li><a href="#">A w odleglej przyszlosci...</a>
    <ul>
        <li><a href="#">W odleglej galaktyce...</a></li>
    </ul>
    </li>
      </ul>
      </li>
  </ul>
  </li>
    </ul>
    </li>
    <li><a href="#">Produkty</a></li>
    <li><a href="#">Download</a></li>
</ul>


Wiem, moze to wyglądać dziwnie ale jest dobrze - tak ma właśnie być smile.gif

Jeśli ktoś potrzebuje podobne rozwiązanie to moje łatwo przerobić do własnych potrzeb...

Bardzo też proszę zainteresowanych o wskazówki i uwagi co można w tym rozwiązaniu ulepszyć...
sf
Jedyne co musisz zrobic to przeczytac jeszcze raz topik o drzewach. Twoje obecne rozwiazanie jest zle bo za duzo robisz zapytan do bazy danych. Jak beda 2 to bedzie OK.
Birkoff
Cytat(sf @ 2006-02-18 10:40:23)
Jedyne co musisz zrobic to przeczytac jeszcze raz topik o drzewach. Twoje obecne rozwiazanie jest zle bo za duzo robisz zapytan do bazy danych. Jak beda 2 to bedzie OK.

Wiem wiem, ja nie mowie ze zastosowalem idealne rozwiazanie ale z drzewem mialem problem (z wygenerowaniem tego specyficznego menu).

Dla kilkunastu elementow w menu te kilka zapytan nie robi roznicy smile.gif
sf
Nastepnym razem nie pros o wskazowki bo szkoda mojego i Twojego czasu winksmiley.jpg
marcini82
Ja bym dodal do tabeli kolumne ilosc_potomkow. W ten sposob znacznie zmniejszylaby sie ilosc zapytan do bazy, bo przed zapytaniem o liste potomkow danej pozycji mozna by sprawdzic te wartosc, i pobierac liste tylko dla pozycji, ktore rzeczywiscie sa rodzicami dla innych pozycji. Unika sie wtedy wysylania zapytania o potomkow tylko po to, aby sie dowiedziec, ze ich liczba wynosi 0.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.