Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Rekurencyjne zapytania kontra przetwarzanie tablic
Forum PHP.pl > Forum > PHP > Pro > Archiwum Pro
Dabroz
Pisząc CMS'a, właśnie zacząłem się zastanawiać nad kwestią rekurencyjnych funkcji wysyłających zapytania SQL. Jeżeli CMS ma strukturę drzewkową, to oczywiście nie można pobrać całości jednym "prostym" zapytaniem tak jak w konstrukcjach płaskich.

I tutaj zaczynam się zastanawiać nad możliwą optymalizacją.

Czy lepszym rozwiązaniem jest pozostawienie w rekurencyjnej fukncji (bądź też pętli) zapytania SQL, czy wywołania bardziej "ogólnego" zapytania, a potem za pomocą tejże funkcji przetwarzanie wyniku aby zbudować drzewko?

Za rekurencyjnym SQL'em przemawia łatwość implementacji... ale chyba nic poza tym. Nie podoba mi się po prostu zmienna ilość zapytań w zależności od poziomu zagnieżdzenia elementu.

A co Wy na ten temat sądzicie?
itsme
wszystko zalezy od sposobu trzymania drzewka ....
ja u siebie wyciagam jednym zapytaniem wszystkie dzieci nastepnie obrabiajac w php mam wszystkich rodzicow ;-)

u mie tez jest rekurenccja lecz na poziomie wyswietlania juz drzewka ktore zostalo wyciagniete jednym zapytaniem

eraz odpowiedz
lepiej nie meczyc bazy i obrobic dane na poziomie php
enceladus
Drzewka można trzymać w taki sposób że jednym zapytaniem wyciąga się całe gałezie (nieśmiertelny artykuł Depesza http://www.depesz.pl - o którym piszę już n-ty raz). Ja osobiście wolę jak najwięcej danych "przygotować" na poziomie odpowiednio zbudowanego zapytania SQL-owych i jak najmniej pracy wykonwywać w php. Tak zbudowany kod wydaje mi się wtedy bardziej czytelny. Do tego bazy danych mają mechanizmy cachowania zapytań i odpowiedzi - warto o tym pamiętać i nie dawać za duzo zadań dla php smile.gif
Dabroz
Zacznę w ten sposób: nie satysfakcjonuje mnie rozwiązanie narzucające maksymalny limit zagnieżdzeń kategorii (CMS ma być możliwie elastyczny).

Doszedłem do pomysłu aby schemat kategorii wyglądał w sposob następujący.

Piewsza, bazowa tabela to cats

Kod
int(11) ID, int(11) PARENT, varchar(32) NAME


Przypuśćmy takie drzewko:

Kod
                  ROOT
                 /    \
            kolory  kształty
           /      \
   niebieski      biały


Zawartość tabeli cats
Kod
ID |PAR|NAME
1  |0  |kolory
2  |0  |kształty
3  |1  |niebieski
4  |1  |biały


Druga tabelka to catrel. Przechowuje ona relacje między kategoriami na zasadzie wiele-do-wielu.

Kod
int(11) CAT_A, int(11) CAT_B, int(6) LEVEL


Gdzie CAT_A i CAT_B to ID'ki wiązanych kategorii a LEVEL to różnica poziomów między nimi - dodatnia oznacza dziecko a ujemna rodzica.

Zawartość catrel dla tego przykładu:

Kod
C_A|C_B|LEV
1  |3  |1
1  |4  |1
3  |1  |-1
4  |1  |-1


(root'a pomijamy, jako że jest ojcem wszystkiego)

Wtedy wyciągnięcie np wszystkich dzieci kategorii %ID% można zrobić za pomocą

  1. SELECT c.NAME, c.ID, r.LEVEL FROM (catrel r LEFT JOIN cats c ON r.CAT_B=c.ID) WHERE r.CAT_A= %ID% AND r.LEVEL > 0


Jak Wam się to podoba?
DeyV
Przy tak sformułowanym pytaniu duże znaczenie ma też przewidywane zastosowanie.
Dlaczego? Ponieważ jeśli przewidujesz dużą ilość kategorii, ale przy stosunkowo niewielkim poziomie zagnieżdżeń, to nie ma po co kombinować z bardzo skomplikowanymi zapytaniami, i złożoną strukturą bazy - ponieważ można pozwolić sobie na osobne zapytanie, dla każdego poziomu drzewka.
Wtedy wystarczy najprostrza struktura typu:
id, parent_id, name ...
Dabroz
A jednak... dzięki takiemu schematowi bazy można pobrać odpowiednią gałąź drzewka jednym zapytaniem. A mówię: nie chcę nic zakładać, kod ma być elastyczny.

[edit] Przejrzałem podaną stronę (depesz.pl) i jedno z rozwiązań jest dosyć podobne do mojego :) - aczkolwiek uważam nadal że moje jest optymalne :)
halfik
serafin: a ja Ci mowie, ze depesz tego nie wymyslil... bazy danych satak stare, cala teoria powstala tak dawno temu, ze na pewno nie wymyslil tego depesz...
Dabroz
Cytat(serafin @ 2004-08-31 14:04:09)
Dabroz, ten schemat nie wymysliles ty a Depesz i wielokrotnie widzialem tak skonstruowane drzewka z podpisem "ja" :/

A ja widzę że Ty wiesz wszystko o wszystkich... Jeżeli nie potrafisz przyjąć do wiadomości że wpadłem na to sam to b. mi przykro... Nikt nie ma monopolu na wiedzę...
.dragonfly
Panowie! Dajcie sobie na wstrzymanie! Odczepcie sie od tych copyrightow. Zaden z was nie jest autorem w/w metody wiec jesli autor zauwazy jakies niepokojace podobienstwa sam zareaguje. Nie potrzebna tutaj jest kolejna klotnia.
jaco
Moje drzewka sa bardzo podobne do tych od itsme (konsultacja na ircu winksmiley.jpg) - nie ma parentow itd., wszystkie informacje zapisane sa w ID rekordu.

Wyciagam wszystko jednym zapytaniem, dalej jest jedna funkcja rekurencyjna tylko do malowania drzewka - calosc dziala bardzo szybko, poziom zagniezdzenia nie ma wplywu na predkosc dzialania skryptu.
Dabroz
Cytat(kAzu^ @ 2004-09-10 23:13:40)
Panowie! Dajcie sobie na wstrzymanie! Odczepcie sie od tych copyrightow. Zaden z was nie jest autorem w/w metody wiec jesli autor zauwazy jakies niepokojace podobienstwa sam zareaguje. Nie potrzebna tutaj jest kolejna klotnia.

Zgadzam się, tym bardziej że to ... nawet gorzej niż offtopik.

Cytat
Wyciagam wszystko jednym zapytaniem, dalej jest jedna funkcja rekurencyjna tylko do malowania drzewka - calosc dziala bardzo szybko, poziom zagniezdzenia nie ma wplywu na predkosc dzialania skryptu.


Używasz szablonów?
jaco
Cytat
Używasz szablonów?


Akurat tam gdzie stosuje to drzewko nie ale nie widze tez wiekszego problemu aby zlecic robote smarty - chocby przez napisanie wlasnej funkcji...

Wlasciwie to cale drzewko malowane jest tylko w panelu admina gdzie nie zwyklem stosowac szablonow - na stronie zazwyczaj maluje tylko liste kategorii o poziom glebiej niz aktualnie wybrana.
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.