BBS的树形结构一直是大家讨论的话题,以前我做都是利用命名规则来实现,这样的好处是表的冗余字段少,结构清楚,容易理解,但其局限性也很明显。感谢廖家远提供算法(实话说,当年算法就没有学好),我决定采用一下这种算法来实现bbs的树形结构。基本思路如下: bbs文章表中有这样几个字段: RootID : 根ID , 新发贴子及其所有子贴都相同。 FatherID:父ID , 父贴子ID Layer: 层数 , 贴子在树中的深度。 OrderNum:排序基数,关键所在,根据它来排序。
基本算法举例如下:
根16(拿个小的举例) idordernumLayer 1 16 0 2 16+16/21 回复第1贴 3 16+16/(2^2)1 回复第1贴 4 16+16/2+16/(2^3) 2 回复第2贴 5 16+16/(2^2)+16/(2^4) 2 回复第3贴
然后,根据排序的结果是(加上回复的深度,就成了树状结构) 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
根据以上思路,我们设计表如下:
/*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注册用户表*/ 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
表结构定了,剩下的就是怎样实现。我把所有相关的功能集成在一个存储过程中,包括贴子本身的存储,其关键是排序基数的生成;父贴子相关字段的更新 ; 根贴相关字段的更新,这些都放到一个事务中,以保持数据的一致性,另外如果父贴要求有回复用email通知,在存储过程中实现发回复email的功能,而不必借助任何asp或其他的组件。这样就使所有任务在一个存储过程中实现。
|