![]() |
![]() ![]() |
![]() |
![]()
Post
#1
|
|
Grupa: Zarejestrowani Postów: 496 Pomógł: 1 Dołączył: 16.01.2008 Skąd: Świnoujście Ostrzeżenie: (0%) ![]() ![]() |
Witam
W jaki sposób rozwiązać problem rozbudowanego drzewa kategorii w skrypcie tak aby zapytania do DB nie trwały zbyt długo i same zapytania były krótkie? Np. serwis allegro ma bardzo rozbudowane drzewo kategorii a mimo tego całość działa płynnie. Obecnie mam to rozwiązanie dość abstrakcyjnie przez co przy rozbudowanym drzewie kategorii zapytanie trwa bardzo długo. Obecna struktura tabeli: id | nazwa | lewa_id | poziom | pozycja | lista lewa_id - id kategorii nadrzędnej; poziom - poziom zagłębienia kategorii; pozycja - pozycja do sortowania przy wyświetlaniu; lista - lista wszystkich podległych kategorii (np. 23,31,75); Z góry dzięki za propozycje rozwiązań Pozdrawiam |
|
|
![]()
Post
#2
|
|
Grupa: Zarejestrowani Postów: 1 933 Pomógł: 460 Dołączył: 2.04.2010 Skąd: Lublin Ostrzeżenie: (0%) ![]() ![]() |
Witam W jaki sposób rozwiązać problem rozbudowanego drzewa kategorii w skrypcie tak aby zapytania do DB nie trwały zbyt długo i same zapytania były krótkie? Np. serwis allegro ma bardzo rozbudowane drzewo kategorii a mimo tego całość działa płynnie. Obecnie mam to rozwiązanie dość abstrakcyjnie przez co przy rozbudowanym drzewie kategorii zapytanie trwa bardzo długo. Obecna struktura tabeli: id | nazwa | lewa_id | poziom | pozycja | lista lewa_id - id kategorii nadrzędnej; poziom - poziom zagłębienia kategorii; pozycja - pozycja do sortowania przy wyświetlaniu; lista - lista wszystkich podległych kategorii (np. 23,31,75); Z góry dzięki za propozycje rozwiązań Pozdrawiam To zależy od tego, czy musisz mieć naraz rozwinięte wszystkie kategorie, czy np. dopiero po kliknięciu na daną kategorię. W drugim przypadku sprawa będzie prostsza. |
|
|
![]()
Post
#3
|
|
Grupa: Zarejestrowani Postów: 655 Pomógł: 73 Dołączył: 2.05.2014 Ostrzeżenie: (0%) ![]() ![]() |
Category
- id - title - parent_id - level - root i teraz masz tak: - telefony (1, telefony, null, 1, 1) -- lg (2, lg, 1, 2, 1) --- coś_tam (5, coś_tam, 2, 3, 1) -- samsung (3, samsung, 1, 2, 1) -- sony (4, sony, 1, 2, 1) - inna (6, inna, null, 1, 2) itp. Powinieneś załapać z czasem, Jest jeszcze left | right, ale to już "wyższa szkoła jazdy" Za kwestie zapytań odpowiada optymalizacja kodu, bazy, indexy a w przypadku np. allegro ilość serwerów (IMG:style_emoticons/default/wink.gif) |
|
|
![]()
Post
#4
|
|
Grupa: Zarejestrowani Postów: 8 068 Pomógł: 1414 Dołączył: 26.10.2005 Ostrzeżenie: (0%) ![]() ![]() |
nested set
|
|
|
![]()
Post
#5
|
|
Grupa: Zarejestrowani Postów: 1 933 Pomógł: 460 Dołączył: 2.04.2010 Skąd: Lublin Ostrzeżenie: (0%) ![]() ![]() |
Aha, polecałbym jeszcze cache. Drzewo kategorii to nie jest coś co często się zmienia.
|
|
|
![]()
Post
#6
|
|
Grupa: Zarejestrowani Postów: 496 Pomógł: 1 Dołączył: 16.01.2008 Skąd: Świnoujście Ostrzeżenie: (0%) ![]() ![]() |
Samo wyświtlanie drzewa działa ok, bo wyświetlane są tylko dwa 'poziomy' czyli kategorie i podkategorie ale w jaki sposób 'sklecić' zapytanie do DB aby wyświetlić wszystkie treści które zostały przyporządkowane do kategorii najniższego rzędu - np. w kategorii 'Telefony' mam 200 podkategorii do których jest możliwe dodanie 'treści' - czy zapytanie musi wyglądać tak:
W takim przypadku zapytanie jest tak długie, że 'serwer się gotuje' |
|
|
![]()
Post
#7
|
|
Grupa: Zarejestrowani Postów: 655 Pomógł: 73 Dołączył: 2.05.2014 Ostrzeżenie: (0%) ![]() ![]() |
Masz źle zbudowane baze. Nie masz mieć mole "children" tylko pole "parent" i potem zapytaniem pobierasz wszystkie kategorie które mają parent = ? lub jedno zapytanie o kategorie główne, czyli np. parent = null i leftjoin parent = :id. Rozumiesz? ;>
|
|
|
![]()
Post
#8
|
|
Grupa: Zarejestrowani Postów: 1 933 Pomógł: 460 Dołączył: 2.04.2010 Skąd: Lublin Ostrzeżenie: (0%) ![]() ![]() |
Samo wyświtlanie drzewa działa ok, bo wyświetlane są tylko dwa 'poziomy' czyli kategorie i podkategorie ale w jaki sposób 'sklecić' zapytanie do DB aby wyświetlić wszystkie treści które zostały przyporządkowane do kategorii najniższego rzędu - np. w kategorii 'Telefony' mam 200 podkategorii do których jest możliwe dodanie 'treści' - czy zapytanie musi wyglądać tak:
W takim przypadku zapytanie jest tak długie, że 'serwer się gotuje' Dodaj LIMIT i paginator. |
|
|
![]()
Post
#9
|
|
Grupa: Zarejestrowani Postów: 496 Pomógł: 1 Dołączył: 16.01.2008 Skąd: Świnoujście Ostrzeżenie: (0%) ![]() ![]() |
Masz źle zbudowane baze. Nie masz mieć mole "children" tylko pole "parent" i potem zapytaniem pobierasz wszystkie kategorie które mają parent = ? lub jedno zapytanie o kategorie główne, czyli np. parent = null i leftjoin parent = :id. Rozumiesz? ;> Możesz podać to na przykładzie? Z paginatorem i limitem bez zmian bo chyba problem leży w długości zapytania do DB... |
|
|
![]()
Post
#10
|
|
Grupa: Zarejestrowani Postów: 8 068 Pomógł: 1414 Dołączył: 26.10.2005 Ostrzeżenie: (0%) ![]() ![]() |
Czy ktoś mnie w ogóle słucha? Do dużych drzew w których modyfikacja jest rzadka a bardzo dużo odczytów najlepiej nadaje się nested set, bo jednym zapytaniem można pobierać różne cuda i to bez skomplikowanych zapytań. Jest trudna w ogólnej obsłudze (dodawanie, usuwanie itp.) ale już wybieranie kategorii jest banalnie proste.
|
|
|
![]()
Post
#11
|
|
Grupa: Zarejestrowani Postów: 655 Pomógł: 73 Dołączył: 2.05.2014 Ostrzeżenie: (0%) ![]() ![]() |
Co rozumiesz przez duże drzewo? Używałem doctrine tree dla 1800 kategorii z 6 level i bylo to wyciąganie armat na wróbla:P Mysle ze kolega ma mniejsze drzewo
|
|
|
![]()
Post
#12
|
|
Grupa: Zarejestrowani Postów: 496 Pomógł: 1 Dołączył: 16.01.2008 Skąd: Świnoujście Ostrzeżenie: (0%) ![]() ![]() |
Co rozumiesz przez duże drzewo? Używałem doctrine tree dla 1800 kategorii z 6 level i bylo to wyciąganie armat na wróbla:P Mysle ze kolega ma mniejsze drzewo Chętnie wyciągnę armaty, biorę pod uwagę najgorsze warianty czli kilka/kilkadziesiąt kategorii i kilka/kilkanaście leveli. Tak jak pisałem, sama obsługa kategorii i tabeli z nimi nie jest problemem, problem jest z zapytaniem do DB kiedy chce wywołać treści przyporządkowane do kategorii ostatniego levelu |
|
|
![]()
Post
#13
|
|
Grupa: Zarejestrowani Postów: 655 Pomógł: 73 Dołączył: 2.05.2014 Ostrzeżenie: (0%) ![]() ![]() |
Robisz to zle. Zamiast pobierać IN() itp. To może lepiej pobierz całość i zmapuj w php w pętlach Itp. Po za tym co rozumiesz przez długie zapytania? Samo in() nie jest niczym wolnym czy cos. Leftjoin tak samo. Chcesz optymalizować a mówisz ze chetnie wyciągniesz armaty...
|
|
|
![]()
Post
#14
|
|
Grupa: Zarejestrowani Postów: 496 Pomógł: 1 Dołączył: 16.01.2008 Skąd: Świnoujście Ostrzeżenie: (0%) ![]() ![]() |
Robisz to zle. Zamiast pobierać IN() itp. To może lepiej pobierz całość i zmapuj w php w pętlach Itp. Po za tym co rozumiesz przez długie zapytania? Samo in() nie jest niczym wolnym czy cos. Leftjoin tak samo. Chcesz optymalizować a mówisz ze chetnie wyciągniesz armaty... To może źle zrozumiałem 'armaty' (IMG:style_emoticons/default/wink.gif) Pobieranie całości nie wiem czy jest dobrym pomysłem jeżeli będzie tam kilka tysięcy wpisów przykorządkowanych do konkretnych kategorii... |
|
|
![]()
Post
#15
|
|
Grupa: Zarejestrowani Postów: 1 933 Pomógł: 460 Dołączył: 2.04.2010 Skąd: Lublin Ostrzeżenie: (0%) ![]() ![]() |
To może źle zrozumiałem 'armaty' (IMG:style_emoticons/default/wink.gif) Pobieranie całości nie wiem czy jest dobrym pomysłem jeżeli będzie tam kilka tysięcy wpisów przykorządkowanych do konkretnych kategorii... Pobieranie całości to najgorszy pomysł jaki może być. Jeśli chodzi o pobieranie wyników dorzuć zwyczajnie zwykłego limita:
Dobrym pomysłem byłoby też założenie indexu na id_cat. Gdyby to był postgres mógłbyś też zrobić tabele dziedziczące z warunkiem WITH (no ale niestety nie jest). Zwróć też uwagę jakie kolumny pobierasz, ogranicz się do minimum, tzn. bierz tylko te, które potrzebujesz. Jeśli np. w którejś przechowujesz spory blok tekstu lub nawet obrazek to wiadomo, że pobranie zawartości musi zająć dłuższą chwilę. Więc zamiast SELECT *, zastosuj SELECT col1, col2, itd. |
|
|
![]() ![]() |
![]() |
Aktualny czas: 19.09.2025 - 04:57 |