Fotografický magazín "iZIN IDIF" každý týden ve Vašem e-mailu.
Co nového ve světě fotografie!
Zadejte Vaši e-mailovou adresu:
Kamarád fotí rád?
Přihlas ho k odběru fotomagazínu!
Zadejte e-mailovou adresu kamaráda:
PHP
Diskuse vs. SQL
8. srpna 2002, 00.00 | Podívejme se na již otřepané téma diskusního fóra, tentokráte z jiného pohledu. Oním pohledem bude SQL se zaměřením se
na množství příkazů na databázový stroj.
Dnešním tématem bych se rád věnoval problematice Diskusního fóra. Jistě mnozí z vás okamžitě namítnou, že o tomto tématu bylo již napsáno spousty článků na mnoha serverech. Proto bych vás rád upokojil tím, že se zde nebudu zabývat kompletním řešením diskusního fóra natož kompletními zdroji1.
Mým cílem je zobrazit diskusní fórum z pohledu SQL, bez kterého se asi žádné fórum neobejde. Především se chci zaměřit na minimalizaci počtu příkazů nutných pro vypsání stromu odpovědí diskuse.
Na webu jsem se často setkal s diskusními fóry, založeným na přístupu, že každý příspěvek obsahuje odkaz na předcházející příspěvek. To umožňuje vytvářet téměř neomezenou stromovou strukturu, ale váže to k sobě i jeden problém. Jakým způsobem ho vypsat? Většina těchto fór používá pro vypsání funkci, která se postupně volá s jednotlivými odkazy a tím vzniká strom.
Tento způsob však nepovažuji do dostatečně účinný. Protože vypsání ne moc složitého stromu, může dosáhnout i 50 příkazů na databázový stroj. Určitě by tento problém šel řešit použitím nějakého netriviálního příkazu z SQL, v takovém případě už sice nebudete muset volat příkaz SQL tak často, ale doba odezvy se dosti prodlouží. V podstatě to ani není řešením problému, pouze ho přesouváte na databázový stroj.
Moje řešení je vcelku prosté a spočívá v pouhém abecedním seřazení. Výpis celého stromu příspěvků se realizuje pouhým jedním SQL příkazem, který, jak jsem již řekl, obsahuje pouze ORDER BY, případně ještě LIMIT. Takovýto příkaz samozřejmě je mnohem více náročný než příkaz pro vypsání jednoho příspěvku, ale vsadil bych se, že celkový čas všech jednotlivých příkazů bude delší než na tento jeden.
Nesouhlasíte? Dobře děláte. Logicky dokážete odvodit, že pro rozsáhlou databázi bude ORDER BY trvat déle. Bohužel tomu, tak nebude. V tip je v tom, že moje řešení přináší i jednu nevýhodu, která je současně i jistou výhodou.
Mluvil-li jsem o tom, že se výpis provádí přes ORDER BY dokážete odvodit, že se bude abecedně řadit nějaký sloupec ID. Aby pak bylo řazení funkční ID bude nabývat různých textových hodnot různé délky. Datový typ tohoto sloupce nakonec způsobí to, že strom bude moci existovat pouze do určité hloubky, stejně jako počet hlavních příspěvků bude omezen. To byla nevýhoda. Výhoda spočívá tom, že při správném nastavení hloubky stromu a množství hlavních příspěvků se o celé fórum nemusíte starat, staré příspěvky, které by stejně někdo nečetl se budou při zadávání nových postupně mazat.
Praktické řešeníUž dost teorie! Nyní se budu zabývat přímo tím, jak to napsat.
Vytvoříme si tabulku:
|
Každý si jistě všimnul sloupců id a id_key. Co je jejich obsahem? Musím připomenout, že lze nastavovat hloubka a šířka databáze2. Základně používám délku 2, ta mi umožňuje vložit 100 hlavních příspěvků3 (00 až 99) a hloubku 127 úrovní (255 / 2). Stejně dobře bych mohl používat délku 3, kde bych získal až 1000 hlavních příspěvků s maximální hloubkou 85 úrovní.4
Co ale obsahují tyto dva sloupce doopravdy? Nejdříve se podíváme na sloupec id. Jeho obsah je jednoduchý obsahuje vždy číslo příspěvku5, které se postupně zvětšuje. Za tímto číslem může následovat další úroveň, která se zapisuje stejně. Těchto úrovní zde může být uvedeno, tolik až do maximální hloubky.
Zatímco sloupec id_key obsahuje pouze číslo příspěvku v první úrovni tj. první dva znaky ze sloupce id. Je to taková malá vzpoura proti, pravidlům databází :-).
Asi to není tolik jasné i když je to strašně jednoduché viz. příklad:
id_key |
id |
Můj popis |
00 | 00 | první hlavní příspěvek |
00 | 0000 | první odpověď na první hlavní příspěvek |
00 | 0001 | druhá odpověď na první hlavní příspěvek |
00 | 0002 | třetí odpověď na první hlavní příspěvek |
00 | 000200 | první odpověď na třetí odpověď na první hlavní příspěvek |
01 | 01 | druhý hlavní příspěvek |
02 | 02 | třetí hlavní příspěvek |
02 | 0200 | první odpověď na třetí hlavní příspěvek |
Neobjasnil jsem, proč vlastně jsem do tabulky zahrnul sloupec id_key, když je obsažen v id. Je to prosté. Většina diskusí co znám řadí hlavní příspěvky od nejnovějších, zatímco při zobrazení odpovědí se provádí výpis od nejstarších, abyste postupovali od známého k neznámému. To vyžaduje dvojité seřazení descendentální podle id_key a současně ascendentální podle id6.
Obyčejný SELECT může vypadat např. takto:
|
Při výpisu poznáte aktuální hloubku aktuálního příspěvku podle délky jeho id. Díky tomu, že je máte seřazené stačí otevírat či zavírat např. <blockquote> pouze podle toho, zda předtím byla úroveň nižší či vyšší. Narazíte však, ještě najeden problémeček. Při používání LIMIT určujete kolik se má vypsat příspěvků v jakékoliv úrovni, nemůžete se tedy divit, že se poslední strom příspěvku může pokračovat na další stránce. Osobně si však myslím, že to není tak velký problém.
Fórum není těžké předělat do formy jako je např. tady na Builderu tj. v podobě, kdy se nejdříve zobrazí jen hlavní příspěvky a teprve po kliknutí se zobrazí daný strom. Mohlo by to být přes SELECTy:
|
Sledování nových příspěvků
K pokročilejší funkci fóra je sledování nových odpovědí. Stačí založit novou tabulku:
|
A můžeme sledovat hned několika způsoby:
- sledování všech nových příspěvků ve všech diskusích
|
- sledování všech nových příspěvků ve vybrané diskusi
|
- sledování všech nových příspěvků pouze ve vybrané větvi stromu
|
Po zařazení nového příspěvku stačí projít tabulku watch následujícím příkazem a získáme seznam e-mailů, na které má být odesláno oznámení.
|
A to je asi vše. S případnými dotazy se na mě obracejte přes diskusní fórum tohoto článku.
V experimentální formě toto fórum běží na pomalém serveru http://svecpetr.crolink.cz/police/phorum_pa/. Do konce srpna roku 2002 si s ním můžete dělat co chcete. Po tomto datu, prosím, do něj nevkládejte nesmyslné příspěvky, protože bude součástí komerčního webu.
1. – Přestože kompletní zdrojové kódy vlastním.
2. – Ta navíc nemusí být symetrická jako je v následujících příkladech.
3. – Každý příspěvek může mít opět 100 odpovědí.
4. – Šířka a hloubka lze zvýšit tím, že se nebudou používat pouze čísla 0-9, ale přidají se i písmena a-z. Případně zvětšením velikosti sloupce id a id_key.
5. – uložené ve formátu např. 00 až 99.
6. – id obsahuje id_key z důvodu aby bylo unikátní a mohlo tvořit primární klíč.
-
25. listopadu 2012
-
30. srpna 2002
-
10. října 2002
-
4. listopadu 2002
-
12. září 2002
-
25. listopadu 2012
-
28. července 1998
-
31. července 1998
-
28. srpna 1998
-
6. prosince 2000
-
27. prosince 2007
-
4. května 2007