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