|
BBS的樹形結(jié)構(gòu)一直是大家討論的話題,以前我做都是利用命名規(guī)則來(lái)實(shí)現(xiàn),這樣的好處是表的冗余字段少,結(jié)構(gòu)清楚,容易理解,但其局限性也很明顯。感謝廖家遠(yuǎn)提供算法(實(shí)話說(shuō),當(dāng)年算法就沒有學(xué)好),我決定采用一下這種算法來(lái)實(shí)現(xiàn)bbs的樹形結(jié)構(gòu);舅悸啡缦拢 bbs文章表中有這樣幾個(gè)字段: RootID : 根ID , 新發(fā)貼子及其所有子貼都相同。 FatherID:父ID , 父貼子ID Layer: 層數(shù) , 貼子在樹中的深度。 OrderNum:排序基數(shù),關(guān)鍵所在,根據(jù)它來(lái)排序。
基本算法舉例如下:
根16(拿個(gè)小的舉例) idordernumLayer 1 16 0 2 16+16/21 回復(fù)第1貼 3 16+16/(2^2)1 回復(fù)第1貼 4 16+16/2+16/(2^3) 2 回復(fù)第2貼 5 16+16/(2^2)+16/(2^4) 2 回復(fù)第3貼
然后,根據(jù)排序的結(jié)果是(加上回復(fù)的深度,就成了樹狀結(jié)構(gòu)) idordernum深度 1 160 3 16+16/(2^2) 1 5 16+16/(2^2)+16/(2^4)2 2 16+16/2 1 4 16+16/2+16/(2^3)2
成了這樣的樹: 1 3 5 2 4
根據(jù)以上思路,我們?cè)O(shè)計(jì)表如下:
/*BBS文章表*/ if exists (select * from sysobjects where ID = object_id("BBS")) drop table BBS go
create table BBS ( IDint primary key identitynot null , RootIDintdefault 0not null , FatherIDint default 0not null , Layertinyintdefault 0not null , ForumID int default 0not null , UserIDintdefault 0not null , Titlevarchar(255)default ""not null , Contenttextdefault "" , PostTimedatetimedefault getdate()not null , FaceIDtinyintdefault 0not null , TotalChilds int default 0 not null , OrderNumfloat default power(2,30) not null , Hitsintdefault 0not null , selectedbit default 0 not null , closedbit default 0 not null , IfEmailbit default 0not null , IfSignaturebitdefault 0not null ) go
/*BBS注冊(cè)用戶表*/ if exists(select * from sysobjects where ID = object_id("BBSUser")) drop table BBSUser go
create table BBSUser ( ID intPrimary key identitynot null , UserNamevarchar(20)default ""not null , Passwordvarchar(10)default ""not null , UserTypetinyintdefault 0 not null , --用戶類型,1為斑竹 Email varchar(100) default ""not null , HomePagevarchar(100) default ""not null , ICQ varchar(20)default ""not null , Signature varchar(255) default ""not null , --簽名 Point intdefault 0 not null , --用戶積分 ) go
表結(jié)構(gòu)定了,剩下的就是怎樣實(shí)現(xiàn)。我把所有相關(guān)的功能集成在一個(gè)存儲(chǔ)過(guò)程中,包括貼子本身的存儲(chǔ),其關(guān)鍵是排序基數(shù)的生成;父貼子相關(guān)字段的更新 ; 根貼相關(guān)字段的更新,這些都放到一個(gè)事務(wù)中,以保持?jǐn)?shù)據(jù)的一致性,另外如果父貼要求有回復(fù)用email通知,在存儲(chǔ)過(guò)程中實(shí)現(xiàn)發(fā)回復(fù)email的功能,而不必借助任何asp或其他的組件。這樣就使所有任務(wù)在一個(gè)存儲(chǔ)過(guò)程中實(shí)現(xiàn)。
|