【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。
|