樹型論壇的快速演算法 (轉)

worldblog發表於2007-12-09
樹型論壇的快速演算法 (轉)[@more@]

樹型論壇的演算法
左輕侯
2001.10.9

 樹型論壇(即階梯式論壇)的實現演算法,是一直被討論的問題。總結起來,一般無非是兩種:第一是遞迴。這種方式最簡單,思路最清楚,但是也最低,特別是進行頁定位的時候。由於每進行一次遞迴,就必須一條查詢,使它在大量併發請求時的負載成為災難性的。因此這種演算法一般不實用。第二是增加一個排序欄位,思路是使用一個特殊設計的欄位,例如排序串或者中值排序基數,來實現貼子的插入,在顯示的時候,只需要為每一個主貼執行一次查詢,將所有得到的記錄按序顯示即可。這種方式在效率上有了很大提高,但是仍然不很理想,而且使得插入的程式碼增加了不必要的複雜性,同時還往往導致了支援層次有限制的問題。
 有沒有一種辦法可以簡單、高效地實現樹型論壇呢?我想到了一種演算法,在顯示速度上應該超過我見的任何類似演算法,實現起來也不復雜。
 思路很簡單:就是完全不理會樹型結構本身,將整個論壇視為一個簡單的順序表。這樣不論任何形式的頁面,只需要一條查詢即可得到。那麼如何實現樹型結構呢?方法是新增兩個格式化欄位,一個記錄順序表的次序,一個記錄樹的層次,對取得的記錄集進行相應格式化,即可得到原汁原味的樹型論壇。
 具體實現方法如下:
1、資料庫結構。只列出必需的欄位,全部為int型:
id:貼子序號
ordernum:排序欄位,按照顯示順序從大到小,最早的一條貼子為1
levelnum:樹的層次,0為主貼,以此類推 
2、顯示。使用一條語句:“ * from article order by ordernum DESC”,得到需要的記錄集。遍歷記錄集,檢查它的levelnum欄位,設定相應的縮排。為0則是主貼,不縮排,為1則縮排一層,以此類推,然後顯示之。
3、插入。關鍵是如何設定ordernum欄位。分為兩種情況:
一是發新的主貼,相當於在順序表的最後新增一條記錄。這樣最簡單,只需要透過查詢,得到max(ordernum),然後將ordernum欄位設定為該值加1即可。
二是跟貼,相當於在順序表的中間插入一條記錄。方法是,先得到插入點的ID(即跟貼的父貼ID),將該貼的ordernum值賦予新貼,然後將所有插入點之前(包括插入點本身)的記錄的ordernum全部加1,等於讓它們在順序表中往後移一位,騰出位置。舉例來說:要在一個ID為23的貼子之後跟貼,首先select得到ID23的ordernum,假設為18,將其賦予新貼的ordernum;然後執行“update article set ordernum = ordernum + 1 where ordernum >= 18”,將新貼之後的貼子全部後移。
 效率分析:
 顯示速度應該不會更快了,僅僅是一條簡單的select,對一個int欄位進行排序,而且支援無限的回覆層次。相比之下,遞迴需要為一個頁面中的每一條貼子進行一次select,對datetime欄位進行排序,而“主貼排序欄位法”需要為每一個主貼進行一次select,對char欄位進行排序。
 最大的問題在於插入時,如果插入的位置很靠前,可能要大量記錄的ordernum欄位。但是告訴我們,這種樹型論壇,回覆一般都集中在第一二頁,極少有人回覆很久以前的貼子,所以偶爾為之,也不會增加太大的負擔。如果你實在不放心,也可以用技術手段強制禁止回覆一段時間之前的貼子。
 本論壇的實現見“開發者資源社群”()的附屬論壇,全部提供,基於+ACCESS。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-990482/,如需轉載,請註明出處,否則將追究法律責任。

相關文章