Diskuze v závislostech - tvorba stromu

January 5, 2007 on 1:36 pm | In Programing |

Diskuze v závislostech mám o dost raději než jen souhrn příspěvků pod nějakým článkem či zápiskem. Asi to i mnozí víte, vždyť jsem už o tom psal krátký zápisek. Přes tuto mou oblibu jsem je zatím na všech stránkách a projektech řešil dosti ošklivým způsobem. Vlastně dvěma ošklivými způsoby najednou. Nástin mého postupu si můžete prohlédnout níže:

function RekurzePrispevek($ID, $odsazeni)
{
$Q = MySQL_Query("SELECT * FROM diskuze WHERE zavislost=$ID");
// Ted vytiskni kazdeho nasledovnika a jejich nasledovniky
while($row = MySQL_Fetch_assoc($Q))
{
pseudokod_vytiskni_komentar();
RekurzePrispevek($row['ID'], $odsazeni + 10);
}
}

První věc je rekurze a druhá o dost ošklivější je volání MySQL_Query pokaždé v této rekurzi. Což je přeci něco odporného (pro dvacetipříspěvkovou diskuzi se MySQL volá 20 různých SQL dotazů!) a proto jsem se s tím rozhodl něco udělat. Dlouho jsem dnes dumal, jak tyto problémy odstranit. Bohužel mě napadla jen jedna smysluplná metoda, která navíc odstraňuje jen jeden neduh (MySQL_Query), rekurzi zachovává. Ale i tak se dle mého názoru jedná o dost velký krok správným směrem. Rekurzi už nějak skousnete, že jo :-) .

Dříve jsem měl jen jeden sloupec pro závislosti - uchovávál ID, na kterém daný komentář závisel (nulu pro takzvané top-level komentáře). Dnes jsem závislosti rozšířil o druhý sloupec - s názvem depend_top uchovávající nejvyšší závislost (tedy ten top-level komentář, na kterém zavisí). Z DB najednou vyberu všechny komentáře týkající se jedné diskuze (tedy se stejnou hodnotou depend_top), následně si je přepíšu do pole (ať se s nimi dá pracovat). Pracovně jsem toto pole pojmenoval $unsorted, protože není seřazeno podle závislostí. Samotné řazení je velice podobné kódu na začátku - jen už se neptám DB, ale rovnou procházím pole již získanými komentaři. Vybíram ty, které závisi na daném ID a následně pro nové ID zavolám tuto rekurzi. A tak dále… až do konce.
function SeradKomentare($unsorted, $ID,& $sorted)
{
// Pro vsecny prvky pole ...
for($x; $x < Count($unsorted); $x++)
{
// .. vyberu jen ty, co zavisi na aktualnim komentari
if($unsorted[$x]['depend'] == $ID)
{
// Priradim je do sorted pole...
$sorted[] = $unsorted[$x];
// ...a zavolam rekurzi na tento komentar
SeradKomentare($unsorted, $unsorted[$x]['ID'], $sorted);
}
}
}

Obrovským neduhem tohoto řesení je nemožnost vzít komentář “odprostřed” a zobrazit takto jen jeho závislost (depend_top je jen pro nejvyšší komentáře, ne pro každého následovníka). Snad to nebude potřeba a eventualně to půjde přeci udělat “starým a ošklivým” způsobem. No a nebo se pokusim vymyslet ještě neco lepšího :-P

2 Comments »

RSS feed for comments on this post. TrackBack URI

  1. nevím nakolik je to ještě aktuální, ale zkoušel jsi traverzování kolem stromu? Viz článek Metody ukládání stromových dat v relačních databázích na Intervalu.

    Comment by Ilja Kuklič — 2007-10-17 #

  2. Uprime receno nezkousel (v dane dobe) - interval vubec nectu…

    Comment by jarcec — 2007-10-19 #

Leave a comment

XHTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>

Powered by WordPress with Pool theme design by Borja Fernandez.
Entries and comments feeds. Valid XHTML and CSS. ^Top^