[ Aleksandar1987 @ 03.02.2010. 20:50 ] @
Pravim klasican forum i treba mi upit za pocetnu stranu foruma koji je ustvari i najslozeniji.

Struktura je sledeca: imamo kategorije, svaka kategorija ima svoje podkategorije itd dokle god... u kategorijama se nalaze teme... u temama se nalaze postovi.
Dakle imamo hijerarhiju kategorija gde ne znamo do koje dubine ce ici.

Tabele (pojednostavljene) izgledaju ovako:

Kategorija:
kategorija_id | naziv | parent_id

Tema:
tema_id | naziv | kategorija_id

Post:
post_id | tekst | tema_id

Potrebno je na jednoj stranici ispisati sve podkategorije neke zadate kategorije ali uz to i koliko svaka podkategorija ima tema i postova (i to se gleda celo stablo ispod te podkategorije, ne samo ta podkategorija).

U pitanju je mySQL baza...
[ bogdan.kecman @ 08.02.2010. 19:35 ] @
http://dev.mysql.com/tech-reso...rticles/hierarchical-data.html

to sto ti imas je "The Adjacency List Model" (nemam ideju kako se zove na srpskom).

ako si jos uvek u fazi modelovanja - ja ti iskreno preporucujem da ides na "The Nested Set Model" posto je znacajno brzi i trosi manje resursa.

u tvom "adjacency list" modelu, ne postoji nacin da izvadis "celo drvo" vec jedan upit moze da ti izvadi drvo do "nekog nivoa dubine" ...

dakle da bi izvadio kategorije do nivoa (dubine) 5 radis self join 4 puta

Code:

SELECT t1.naziv AS nivo1, t2.naziv AS nivo2, t3.naziv AS nivo3, t4.naziv AS nivo4, t5.naziv AS nivo5
FROM kategorija AS t1
LEFT JOIN kategorija AS t2 ON t2.parent_id = t1.kategorija_id
LEFT JOIN kategorija AS t3 ON t3.parent_id = t2.kategorija_id
LEFT JOIN kategorija AS t4 ON t4.parent_id = t3.kategorija_id
LEFT JOIN kategorija AS t5 ON t5.parent_id = t4.kategorija_id


ako oces jos jedan nivo .. dodas jos jedan left join ... i tako koliko ti treba ... kao sto rekoh - smor na kvadrad (to je sa nested set modelom laganica)

ako hoces samo "krajnje" nodove .. dakle kategorije bez podkategorija (sto moze da bude zgodno za forum - ako su poruke samo u kranjim nodovima, mada, gledajuci phpbb na primer to nije tako) onda je to mnogo jednostavnije

Code:

SELECT t1.naziv FROM kategorija AS t1 LEFT JOIN kategorija as t2 ON t1.kategorija_id = t2.parent_id WHERE t2.kategorija_id IS NULL;



sve u svemu ... "smor" ... posebno sto ako nedaj boze ne pazis sta radis i obrises nod koji ima podnodove ... ima da ga nadjes - al nikad .. nested sed rulez kada ga skapiras .. a na linku spocetka posta imas full objasnjenje kako se isti koristi ... to nije samo zgodno u mysql-u vec i ako koristis bilo koji drugi rdbms.

u oraklu, db2 i jos nekim rdbms-ovima bi adjacency list mogao da se iskuca tako da ti vuce celo drvo odjednom ... na primer u oraklu mozes da uradis
Code:

SELECT  lpad(' ', (level - 1) * 2) || naziv AS formatiran_naziv,   kategorija_id,   parrent_id,   level
FROM kategorija
CONNECT BY PRIOR kategorija_id = parrent_id
START WITH kategorija_id = 1;

skroz iskusno .. ali CONNECT BY PRIOR koje ima oracle ce na mysql mozda da dodju sad kada nas je BigO kupio .. no u svakom slucaju, za to ce malo da sacekamo :(
[ Aleksandar1987 @ 14.02.2010. 12:08 ] @
Hvala na odgovoru :). Naisao sam na to resenje i ranije ali mi se nije ucinilo optimalnim ali sad gledam i to je to. Razmisljao sam i u pravcu da dodam jedno polje "path" (tipa 1.1.2, 1.1.3 itd) pa da sa LIKE-om selektujem podkategorije. Sta ti mislis o tom resenju?
[ bogdan.kecman @ 14.02.2010. 20:51 ] @
Citat:
Aleksandar1987: Sta ti mislis o tom resenju?


nista dobro ... to resenje je sporo do zla boga :( ... bilo kakve pretrage po funkcijama limitaraju mogucnosti indexiranja "da valja" tako da dobijas opterecen sistem ... to ce da radi na par stotina slogova ali sa porastom broja slogova exponencijalno postaje sporije

"The Nested Set Model" je mnogo jednostavnije resenje koje radi. imas primer na linku koji sam ti dao primere kako radis sve bitne operacije sa tim drvetom (dodavanje nodova, brisanje nodova, pretraga nodova, setnja kroz drvo ..) - ovaj model nije toliko popularan samo zato sto je 90% programera neupoznato sa bilo kakvim teorijama pa direktno iz glave prave dizajn 1:1 iz onoga kako oni vide sistem direktno u bazu ... ali je sistem mnoooogo brzi od bilo cega za slicnu namenu