Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> PHP/MySQL, Wyświetlanie produktów z **(nad kategorii/drzewa kategorii)
ksenonlogin
post
Post #1





Grupa: Zarejestrowani
Postów: 123
Pomógł: 3
Dołączył: 29.10.2011

Ostrzeżenie: (0%)
-----


Witam

Problem wygląda tak:

mam dwie tabele: kategorie oraz przedmiot, wiadomo że w przedmiocie(aukcji) zawierają się klucze o wartości "id_kategoria", jednak tabela przedstawia drzewo kategorii więc produkt jest przypięty do końcówki (kategoria "laptop" zawiera "acer" oaz "samsung" więc Acer inspiron X3 będzie zawierał klucz z "acer" anie z "laptop"), i właśnie tu zaczyna się problem: jak kliknę na link acer to wyświetlę spokojnie acery ale jak kliknę "laptop" to jak mam wyświetlić produkty podkategorii zachowując sortowanie ogólne (np. produkty po czasie rejestracji) - wspomnę iż zagłębienie kategorii jest nieograniczone.

Niżej przedstawiam tabelę oraz funkcję rysującą drzewo kategorii.

Tabela aukcji:
  1. CREATE TABLE IF NOT EXISTS `przedmiot` (
  2. `id_przedmiot` mediumint(8) UNSIGNED NOT NULL AUTO_INCREMENT,
  3. `klucz_user_przedmiot` mediumint(8) UNSIGNED DEFAULT NULL,
  4. `klucz_kategoria_przedmiot` mediumint(7) UNSIGNED NOT NULL,
  5. `zdjecie_przedmiot` varchar(60) COLLATE utf8_unicode_ci NOT NULL,
  6. `tytul_przedmiot` varchar(70) COLLATE utf8_unicode_ci NOT NULL,
  7. `krotki_opis_przedmiot` varchar(300) COLLATE utf8_unicode_ci NOT NULL,
  8. `klucz_opis_przedmiot_przedmiot` mediumint(8) UNSIGNED NOT NULL,
  9. `cena_przedmiot` double(10,2) UNSIGNED NOT NULL,
  10. `stan_magazynowy_przedmiot` mediumint(5) UNSIGNED NOT NULL,
  11. `czas_trwania_przedmiot` tinyint(2) UNSIGNED DEFAULT NULL,
  12. `klucz_opcje_dostawy_koszt_przedmiot` mediumint(8) UNSIGNED NOT NULL,
  13. `wysylka_w_ciagu_przedmiot` tinyint(1) UNSIGNED DEFAULT NULL,
  14. `faktura_vat_przedmiot` tinyint(1) UNSIGNED DEFAULT NULL,
  15. `dotadkowe_informacje_przedmiot` varchar(500) COLLATE utf8_unicode_ci DEFAULT NULL,
  16. `p_stronaglowna_przedmiot` tinyint(1) UNSIGNED NOT NULL,
  17. `p_stronakategorii_przedmiot` tinyint(1) UNSIGNED NOT NULL,
  18. `p_wyroznienieproduktu_przedmiot` tinyint(1) UNSIGNED NOT NULL,
  19. `p_podswietlenie_przedmiot` tinyint(1) UNSIGNED NOT NULL,
  20. `p_produktwpromocja_przedmiot` double(10,2) UNSIGNED NOT NULL,
  21. `status_przedmiot` tinyint(2) DEFAULT NULL,
  22. `data_rejestracji_przedmiot` datetime NOT NULL,
  23. `data_zakonczenia_przedmiot` datetime DEFAULT NULL,
  24. PRIMARY KEY (`id_przedmiot`),
  25. KEY `krotki_opis_przedmiot_2` (`krotki_opis_przedmiot`),
  26. KEY `tytul_przedmiot_3` (`tytul_przedmiot`),
  27. KEY `krotki_opis_przedmiot_3` (`krotki_opis_przedmiot`),
  28. FULLTEXT KEY `tytul_przedmiot` (`tytul_przedmiot`),
  29. FULLTEXT KEY `krotki_opis_przedmiot` (`krotki_opis_przedmiot`),
  30. FULLTEXT KEY `tytul_przedmiot_2` (`tytul_przedmiot`),
  31. FULLTEXT KEY `tytul_przedmiot_4` (`tytul_przedmiot`),
  32. FULLTEXT KEY `krotki_opis_przedmiot_4` (`krotki_opis_przedmiot`)
  33. ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=10000586 ;



Tabela kategorie:
  1. CREATE TABLE IF NOT EXISTS `kategoria` (
  2. `id_kategoria` mediumint(7) UNSIGNED NOT NULL AUTO_INCREMENT,
  3. `rodzic_kategoria` mediumint(7) UNSIGNED NOT NULL,
  4. `nazwa_kategoria` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL,
  5. `tytul_kategoria` varchar(30) COLLATE utf8_unicode_ci DEFAULT NULL,
  6. `meta_description` varchar(700) COLLATE utf8_unicode_ci DEFAULT NULL,
  7. `meta_keywords` varchar(500) COLLATE utf8_unicode_ci DEFAULT NULL,
  8. `przyjazny_url_kategoria` varchar(400) COLLATE utf8_unicode_ci DEFAULT NULL,
  9. `status_kategoria` smallint(5) UNSIGNED NOT NULL,
  10. PRIMARY KEY (`id_kategoria`)
  11. ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=10000228 ;




Funkcja rysująca drzewo:

  1. function view_category_ul_li_tree_root($rodzic_kategoria, $level) { $result = mysql_query("SELECT a.id_kategoria, a.nazwa_kategoria, a.przyjazny_url_kategoria, Deriv1.Count FROM `kategoria` a LEFT OUTER JOIN (SELECT rodzic_kategoria, COUNT(*) AS Count FROM `kategoria` GROUP BY rodzic_kategoria) Deriv1 ON a.id_kategoria = Deriv1.rodzic_kategoria WHERE a.rodzic_kategoria=" . $rodzic_kategoria);
  2.  
  3. while ($row = mysql_fetch_assoc($result)) {
  4.  
  5. if ($row['Count'] > 0) {
  6.  
  7. $ar .= '<li id="id' . $row['id_kategoria'] . '" class="folder"><span><a href="#" onClick="loadPage1(\'./index.php?view=category&action=editcategory&decision=show&type_of_loading=ajax&delete=no&id_category=' . $row['id_kategoria'] . '\');">' . $row['nazwa_kategoria'] . '</a></span>
  8. <ul>'.view_category_ul_li_tree_root($row['id_kategoria'], $level + 1).'</ul></li>';
  9.  
  10. } elseif ($row['Count'] == 0) {
  11. $ar .= '<li class="noLink" id="id' . $row['id_kategoria'] . '"><span><a href="#" onClick="loadPage1(\'./index.php?view=category&action=editcategory&decision=show&type_of_loading=ajax&delete=yes&id_category=' . $row['id_kategoria'] . '\');">' . $row['nazwa_kategoria'] . '</a></span></li>';
  12. }
  13. }
  14. return $ar;
  15. }
Go to the top of the page
+Quote Post
sebastian.rozmus
post
Post #2





Grupa: Zarejestrowani
Postów: 48
Pomógł: 12
Dołączył: 7.03.2012

Ostrzeżenie: (0%)
-----


Możesz zrobić to zagnieżdzając zapytania MySQL albo dodając pole varchar zawierające numery id wszystkich kategorii od aktualnej do samej góry. Np.:

Acer; ID: 1; ścieżka: "1,"
Inspiron X3; ID: 2; ścieżka: "1,2,"

Ścieżkię generujesz przy dodawaniu przedmiotu. A zapytanie coś w tym stylu:

  1. SELECT przedmiot p LEFT JOIN kategoria k ON k.id_kategoria = p.klucz_kategoria_przedmiot WHERE k.sciezka LIKE '{$sciezka_aktualnej_kategorii}%'


Wydaje mi się, że rozwiązanie jest dobre, choć niezbyt eleganckie. Jeśli nie jest dobre, to poproszę o krytykę (IMG:style_emoticons/default/smile.gif)
Go to the top of the page
+Quote Post
ksenonlogin
post
Post #3





Grupa: Zarejestrowani
Postów: 123
Pomógł: 3
Dołączył: 29.10.2011

Ostrzeżenie: (0%)
-----


Mi za bardzo to nie pasuje, jeżeli kategoria będzie częścią podkategorii to trzeba się liczyć z tym że przy dużej liczbie kategorii i zagnieżdżeń będzie taki moment że połączona ścieżka stworzy jakąś kategorię (chyba że tak jak napisałeś jest to pole varchar czymś tam rozdzielone) jednak rzeczywiście jest to nieeleganckie (IMG:style_emoticons/default/wink.gif)

wolałbym coś praktycznego, ponieważ kończę pisać dość pokaźny sklep jednak zatrzymałem się własnie na tej niby banalnej rzeczy (po prostu nie mogę sobie tego działania w głowie ułożyć)

Czekam na więcej pomysłów jak by było można to wykombinować (IMG:style_emoticons/default/wink.gif)
Go to the top of the page
+Quote Post
mortus
post
Post #4





Grupa: Zarejestrowani
Postów: 2 178
Pomógł: 596
Dołączył: 25.09.2009
Skąd: Piwniczna-Zdrój

Ostrzeżenie: (0%)
-----


@sebastian.rozmus: Oczywiście rozwiązanie jest jak najbardziej dobre i ma nawet swoją nazwę - drzewo IP.

@ksenonlogin: Niestety przy takiej budowie systemu kategorii i podkategorii, która opiera się jedynie na id i parentId ciężko będzie znaleźć wydajne rozwiązanie. Musisz bowiem napisać sobie funkcję rekurencyjną, która wyszuka wszystkie podkategorie w danej kategorii i w jej podkategoriach, i tak w kółko. Znalezione id podkategorii wrzucasz do zapytania:
SELECT ... FROM `przedmiot` WHERE `klucz_kategoria_przedmiot` IN (tutaj znalezione identyfikatory kategorii)
Niestety funkcja rekurencyjna wykonywać będzie masę zapytań SQL, co zdecydowanie wpłynie na spadek wydajności aplikacji i wyszukiwanie podkategorii danej kategorii trochę czasu zajmie (oczywiście to zależy od ilości kategorii i podkategorii). Zdecydowanie lepszym rozwiązaniem będą tutaj zaproponowane wyżej drzewa IP.

Oczywiście są jeszcze inne sposoby na zaimplementowanie drzewa kategorii, a wszystkie je łączy wspólny element - zbiory zagłębione (nested sets).
Go to the top of the page
+Quote Post
ksenonlogin
post
Post #5





Grupa: Zarejestrowani
Postów: 123
Pomógł: 3
Dołączył: 29.10.2011

Ostrzeżenie: (0%)
-----


Szukałem szukałem i nic nie znalazłem więc zrobiłem według waszych zaleceń i powiem szczerze że jest ok - nie daje znacznego obciążenia (IMG:style_emoticons/default/wink.gif)

Dzięki (IMG:style_emoticons/default/wink.gif)
Go to the top of the page
+Quote Post
alegorn
post
Post #6





Grupa: Zarejestrowani
Postów: 341
Pomógł: 40
Dołączył: 23.06.2009

Ostrzeżenie: (0%)
-----


@mortus nested sets jest trudnym sposobem implementacji drzewka (trochę nieintuicyjne na początek)
jednak jak sie człowiek zagłębi w temat - to widać same zalety :]

tutaj topic odpisałem jak można łatwo wybrać cala gałąź drzewka.

drzewa z rodzicem - są ok, ale tylko wtedy gdy znamy ilość zagłębień, no i tych zagłębień nie jest zbyt wiele.
inaczej - wychodzi makabra, ilość zapytań jaka trzeba wysłać by pobrać pełne drzewo jest koszmarna...
j.
Go to the top of the page
+Quote Post
ksenonlogin
post
Post #7





Grupa: Zarejestrowani
Postów: 123
Pomógł: 3
Dołączył: 29.10.2011

Ostrzeżenie: (0%)
-----


Przekonaliście mnie, powiem szczerze że nawet większy porządek i w razie problemu z bazą łatwiej znaleźć problem przy zagubionych elementach (IMG:style_emoticons/default/wink.gif)

@alegorn: dzięki za dodatkowy temat przydał się ;:
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 29.08.2025 - 23:58