ALL IN ONE : 利用存储过程实现BBS树形结构的存储及有回复email通知(不必借助任何组件发Email)功能

发表于:2007-06-30来源:作者:点击数: 标签:
BBS的树形结构一直是大家讨论的话题,以前我做都是利用命名规则来实现,这样的好处是表的冗余字段少,结构清楚,容易理解,但其局限性也很明显。感谢廖家远提供算法(实话说,当年算法就没有学好),我决定采用一下这种算法来实现bbs的树形结构。基本思路如下
    BBS的树形结构一直是大家讨论的话题,以前我做都是利用命名规则来实现,这样的好处是表的冗余字段少,结构清楚,容易理解,但其局限性也很明显。感谢廖家远提供算法(实话说,当年算法就没有学好),我决定采用一下这种算法来实现bbs的树形结构。基本思路如下:
    bbs文章表中有这样几个字段:
    RootID :   根ID , 新发贴子及其所有子贴都相同。
    FatherID:  父ID , 父贴子ID
    Layer:     层数 , 贴子在树中的深度。
    OrderNum:  排序基数,关键所在,根据它来排序。

基本算法举例如下:

根16(拿个小的举例)
id    ordernum              Layer                
1     16                     0
2     16+16/2                1   回复第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贴

然后,根据排序的结果是(加上回复的深度,就成了树状结构)
id      ordernum                  深度
1       16                          0
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
             (
        ID        int primary key identity        not null ,
                RootID        int        default 0        not null ,  
        FatherID    int         default 0        not null ,
        Layer        tinyint        default 0        not null ,
                ForumID         int             default 0        not null ,
        UserID        int        default 0        not null ,
        Title        varchar(255)    default ""        not null ,
        Content        text        default ""             ,
        PostTime    datetime    default getdate()    not null ,
        FaceID        tinyint        default 0        not null ,
                TotalChilds     int             default 0               not null ,
                OrderNum        float           default power(2,30)     not null ,
        Hits        int        default 0        not null ,
                selected        bit             default 0               not null ,
                closed          bit             default 0               not null ,
        IfEmail        bit         default 0        not null ,
        IfSignature    bit        default 0        not null
           )
go
                  

/*BBS注册用户表*/
if exists(select * from sysobjects where ID = object_id("BBSUser"))
   drop table BBSUser
go

create table BBSUser
             (
               ID       int        Primary key identity    not null ,
               UserName    varchar(20)    default ""              not null ,
               Password    varchar(10)  default ""              not null ,
               UserType    tinyint      default 0               not null , --用户类型,1为斑竹
               Email       varchar(100) default ""              not null ,
               HomePage    varchar(100) default ""              not null ,
               ICQ         varchar(20)  default ""              not null ,
               Signature   varchar(255) default ""              not null , --签名
               Point       int          default 0               not null , --用户积分
              )
go    


    表结构定了,剩下的就是怎样实现。我把所有相关的功能集成在一个存储过程中,包括贴子本身的存储,其关键是排序基数的生成;父贴子相关字段的更新 ; 根贴相关字段的更新,这些都放到一个事务中,以保持数据的一致性,另外如果父贴要求有回复用email通知,在存储过程中实现发回复email的功能,而不必借助任何asp或其他的组件。这样就使所有任务在一个存储过程中实现。

原文转自:http://www.ltesting.net