Optimizare forum cu posturi indentate la parinte

Inainte de a va apuca sa implementati un forum cu posturi indentate la postul parinte ar fi indiat sa cititi articolul urmator: Discussions: Flat or Threaded?

Daca inca tot vreti sa implementati un forum cu posturi indentate la parinte atunci sa discutam optiunile pe care le avem.

Prima optiune este cea in care salvam in DB parintele fiecarui copil.
Apoi cand incarcam rezultatele, interogam in DB pentru fiecare parinte sa ii aflam copii apoi pentru fiecare copil sa ii aflam copii si asa mai departe. Problema cu aceasta abordare este exact faptul ca trebuiesc facute foarte multe interogari - selecturi in DB pentru a construi structura de copac (tree).
Deci aceasta optiune este neperformanta la selectarea posturilor.

O alta abordare este sa adaugam la posturi o coloana numita "order" iar cand adaugam un post nou, calculam ca le post se face reply, punem postul nou cu order +1 fata de raspuns si updatam in sus posturile celalte.
Astfel la select - vom lua posturile gata ordonate dupa parintele la care s-a rapuns.
Problema cu aceasta abordare este updateul care trebuie facut utilizand Lock table. Si este indicat sa se foloseasca Lock pentru ca daca sunt doua posturi simultan care updateaza restul posturilor din thread si nu exista Lock, atunci se vor updata gresit iar threadul va fi corupt. Deci aceasta varianta este foarte rapida la selectarea posturilor insa este foarte greoaie la inserarea de post nou si eventual problematica daca exista queriuri care fac LOCK simultan pe tabel.

O alta varianta pe care am dezvoltat-o noi, presupune salvarea nivelului in DB la INSERT si apoi efectuarea unui singur SELECT cand se iau posturile.
Aceasta abordare funcitoneaza unde stim numarul de niveluri - in cazul unui form de obicei sunt cam 3-4 niveluri de indentare maxim.
Deci adaugam in DB la posturi o coloana numita "level" si cand adaugam un post nou, salvam si nivelul pe care este postul curent -1, 2, 3 sau 4 sa zicem.

Cand avem un reply la un post de pe nivelul 4, salvam tot nivelul 4 si mai adaugam o coloana la posts - "last_level_parent" unde salvam ultimul parinte de pe nivelul 3 - ca sa stim unde pozitionam acest post.

Acum, cand luam posturile din db, le selectam pe toate din threadul respectiv si apoi dupa ce le luam din db, iteram o singura data prin ele pentru a le organiza in array uri pe niveluri.
Un lucru foarte important aici este sa salvam fiecare array de nivel avand ca si cheie - idul perintelui.
Apoi la randare facem un loop pentru posturile din nivelul 1.
Pentru fiecare nivel 1, verificam daca array ul de nivel 2 contine vre-un element cu cheia idului postului de pe nivelul 1. Daca contine, atunci randam si nivelul 2 intr-un loop. Si apoi pentru fiecare post de nivel 2, verificam daca are un corespondent in arrayul de nivel 3 si facem si 4.

Aceasta abordare este mai rapida (pentru forumuri si posturi) deoarece selectul este foarte simpu - nu facem decat un singur SELECT in DB, la update nu trebuie sa updatam toate posturile cu order. Tot ce avem de facut in plus este un loop prin toate posturile pentru a le orgraniza pe niveluri.
Cu siguranta insa ca exista si implementari mai bune pentru posturi si daca cunoasteti o astfel de implementare va rugam sa ne-o spuneti si noua.

by AlexT

E-mail

office@pixel-works.ro

Telephone

+40 (0)741 581 186

Adress

Bloc C2, sc. B, ap. 2, Buzau, Romania.