WEB开发网
开发学院WEB开发ASP bbs树形结构的实现方法(一) 阅读

bbs树形结构的实现方法(一)

 2000-12-06 10:54:25 来源:WEB开发网   
核心提示:【bigeagle】 于 2000-12-6 14:38:50 加贴在 Joy asp ↑:bbs的树形结构显示可以有很多种方法,其中比较容易想到的是递归和排序串方法,bbs树形结构的实现方法(一),但这两种方法并不是很好,那么怎样才算是比较合理的算法呢?递归方法不用讲,但只使用select就得到了正确的结构列表,看了
【bigeagle】 于 2000-12-6 14:38:50 加贴在 Joy asp ↑:

  bbs的树形结构显示可以有很多种方法,其中比较容易想到的是递归和排序串方法,但这两种方法并不是很好,那么怎
样才算是比较合理的算法呢?
  递归方法不用讲,大家都知道怎么用,先讲讲排序串方法,最简单的排序串方法可以这样用,只用一个id就可以完成树
型,向这样
1 001
2 002
3 001001
4 001001001
5 001002001
用这个字符串排序后就变成这样:
001
  001001
     001001001
  001002001
002
这种方法容易实现,但缺点也是很明显,一个是回帖数受限制,另一个随着回帖增加会越来越长,影响数据库效率。 

下面一种方法是李龙的,属于变通的排序串方法
DDL
--------------
CREATE TABLE dbo.Message
(
  ID     numeric(18,0) IDENTITY(1000,1),
  DateAndTime datetime   DEFAULT getdate() NOT NULL,
  AuthorID  numeric(18,0) NOT NULL,
  Subject   nvarchar(250) NOT NULL,
  Body    ntext     NULL,
  LinkURL   nvarchar(100) NULL,
  TextForLink nvarchar(50) NULL,
  ImageURL  nvarchar(100) NULL,
  Class    int      DEFAULT 0 NOT NULL,
  ClientInfo nvarchar(250) NULL,
  RemoteAddr nvarchar(50) NULL,
  CONSTRAINT PK_BBSMessage
  PRIMARY KEY NONCLUSTERED (ID,AuthorID)
)
go
CREATE TABLE dbo.MsgRefTab
(
  MsgID   numeric(18,0) NOT NULL,
  ParentID  numeric(18,0) NOT NULL,
  AncestorID numeric(18,0) NOT NULL,
  ChildNum  numeric(18,0) DEFAULT 0 NOT NULL,
  LinkStr  nvarchar(250) NOT NULL,
  CONSTRAINT PK_BBSRefTab
  PRIMARY KEY NONCLUSTERED (MsgID)
)
go
-----------------
存储过程:
-----------------
-- 抽出
CREATE PROCEDURE sp_Summary
@HaveBody bit,
@from numeric,
@to numeric
AS
IF (@HaveBody = 1)
select t.ID,t.DateAndTime,m.Nickname as
Author,m.Email,t.Subject,t.Body,t.LinkURL,t.TextForLink,t.ImageURL,s.ChildNu
m,s.ParentID
from Message t
 ,MsgRefTab AS s
 ,(SELECT MsgID FROM MsgRefTab WHERE ParentID = 0) AS f
 ,Members AS m
where t.ID=s.MsgID
 and f.MsgID = s.AncestorID
 and f.MsgID between @from and @to
 and m.MemberID = t.AuthorID
order by s.AncestorID,s.LinkStr
ELSE
select t.ID,t.DateAndTime,m.Nickname as
Author,m.Email,t.Subject,t.LinkURL,t.TextForLink,t.ImageURL,s.ChildNum,s.Par
entID
from Message t
 ,MsgRefTab AS s
 ,(SELECT MsgID FROM MsgRefTab WHERE ParentID = 0) AS f
 ,Members AS m
where t.ID=s.MsgID
 and f.MsgID = s.AncestorID
 and f.MsgID between @from and @to
 and m.MemberID = t.AuthorID
order by s.AncestorID,s.LinkStr
go

-- 加贴

CREATE PROCEDURE sp_Add_Message
@AuthorID numeric,
@Subject nvarchar(250),
@Body ntext,
@LinkURL nvarchar(100),
@TextForLink nvarchar(50),
@ImageURL nvarchar(100),
@ParentID numeric,
@ID numeric OUTPUT,
@ChildNum numeric OUTPUT,
@LinkStr nvarchar(250) OUTPUT,
@AncestorID numeric OUTPUT
AS
INSERT INTO Message(
 AuthorID,
 Subject,
 Body,
 LinkURL,
 TextForLink,
 ImageURL)
VALUES(
 @AuthorID,
 @Subject,
 @Body,
 @LinkURL,
 @TextForLink,
 @ImageURL)

SELECT @ID = @@IDENTITY

UPDATE MsgRefTab
SET
 ChildNum = ChildNum+1
WHERE
 MsgID = @ParentID

SELECT @ChildNum = ChildNum,
 @LinkStr = LinkStr,
 @AncestorID = AncestorID
FROM MsgRefTab
WHERE
 MsgID = @ParentID
go

---
是基于这样的想法:
贴子和跟贴都放在message表里,另有MsgRefTab对每一条信息都有描述。
父贴ParentID,0为不是子贴
祖宗贴AncestorID
直接跟贴数ChildNum
联接串LinkStr,学问都在这里,所有的跟贴都用一个数字字符串表示
如是
1011--->      为空
1012--->001     1011的跟贴,父贴LinkStr+父贴的子贴数+1
1013--->001001   1012的跟贴,父贴LinkStr+父贴的子贴数+1
1018--->001001001  1013的跟贴,父贴LinkStr+父贴的子贴数+1
1014--->001002   1012的跟贴,父贴LinkStr+父贴的子贴数+1
1017--->001002001  1014的跟贴,父贴LinkStr+父贴的子贴数+1

部分演示数据:
MsgID ParentID AncestorID ChildNum LinkStr
1010 0    1010    0
1011 0    1011    1
1012 1011   1011    3    001
1013 1012   1011    1    001001
1014 1012   1011    1    001002
1015 0    1015    0
1017 1014   1011    0    001002001
1018 1013   1011    0    001001001

就是算法复杂一点,但只使用select就得到了正确的结构列表。
看了这么多bbs的算法,还是觉得自己的方法好,现实中由存储过程直接生成xml文档,交
给client。



Tags:bbs 树形 结构

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接