程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> SqlServer數據庫 >> 關於SqlServer >> 評論、回復數據表設計之我見

評論、回復數據表設計之我見

編輯:關於SqlServer

  出於興趣,近期做了一個圖片分享的小項目,其中在做有關圖片的評論以及回復的功能時,剛開始對於這中功能有一些糾結,糾結的是評論與回復的內容是放在兩個表還是一個表中,對於放在兩張表的結構考慮到後期的數據讀取的復雜問題,最後決定將評論和回復的功能都放在同一張表中。數據庫采用SqlServer,具體表設計如下:

 CREATE TABLE [dbo].[DemoComment](
     [RowGuid] [nvarchar](50) NOT NULL,
     [ParentGuid] [nvarchar](50) NULL,
     [CommentText] [nvarchar](200) NULL,
     [CommentUserGuid] [nvarchar](50) NULL,
     [CommentUserName] [nvarchar](50) NULL,
     [CommentDate] [datetime] NULL,
     [ToUserGuid] [nvarchar](50) NULL,
     [ToUserName] [nvarchar](50) NULL,
     [CommentPictureGuid] [nvarchar](50) NULL
 )

  然後對每一張圖片的評論就會有兩種情況:1、評論。2、評論和回復。現假設有"person_A"和"person_B"兩人對圖片"pic"評論,則有

1、評論情況就是簡單的插入一條評論記錄:

 insert into DemoComment(RowGuid,CommentText,CommentUserGuid,CommentUserName,CommentDate,CommentPictureGuid)
 values(NEWID(),'wow,nice pic!','person_A_Guid','person_A',getdate(),'pic');
 insert into DemoComment(RowGuid,CommentText,CommentUserGuid,CommentUserName,CommentDate,CommentPictureGuid)
 values(NEWID(),'wow,what a nice pic!','person_B_Guid','person_B',getdate(),'pic');

則用戶浏覽圖片詳細時,可以看到圖片“pic”下有如下兩條評論:

 

 

此時,有“person_C”是“person_B”的好友,“person_C”在“person_B”的評論下進行了回復,則有

2、“person_C”對“person_B”評論的回復

 insert into DemoComment(RowGuid,ParentGuid,CommentText,CommentUserGuid,CommentUserName,CommentDate,ToUserGuid,ToUserName,CommentPictureGuid)
 values(NEWID(),'E07E9026-0194-4695-9FE4-FDD4DF9D3865','yes,I want to get one!','person_C_Guid','person_C',getdate(),'person_B_Guid','person_B','pic');

然後“person_B”也對“person_C”進行了回復

 insert into DemoComment(RowGuid,ParentGuid,CommentText,CommentUserGuid,CommentUserName,CommentDate,ToUserGuid,ToUserName,CommentPictureGuid)
 values(NEWID(),'B688AB26-22D8-42BF-A518-10E3EFDC041F','OK,I will buy one for you!','person_B_Guid','person_B',getdate(),'person_C_Guid','person_C','pic');

然後“person_C”也對“person_B”表達了謝意。

 insert into DemoComment(RowGuid,ParentGuid,CommentText,CommentUserGuid,CommentUserName,CommentDate,ToUserGuid,ToUserName,CommentPictureGuid)
 values(NEWID(),'81E882B3-9232-40C7-8BBD-F1E821063B64','really,Thank you very muck!','person_C_Guid','person_C',getdate(),'person_B_Guid','person_B','pic');

至此,所有的評論與回復已全部完成。

現在要做的就是取出對“pic”的所有評論和回復。

注意,此時可不是簡單地按照時間進行排序,假設“person_A”開始做了5條評論,過了一段時間"person_B"對“person_A”的第一條評論進行了回復,如果按時間排序肯定出錯。這是就可以看到“RowGuid”和“ParentGuid”的關系了:

沒錯,RowGuid和ParentGuid具有關聯關系,我們要做的就是找到第一條評論的RowGuid,然後與之關聯的評論與回復就可以全部取出了。這裡有一點遞歸的意思。

定義一個存儲過程,取出某一條評論下的所有回復:

 procedure [dbo].[sp_GetCommnetsByRowGuid] (@RowGuid nvarchar(50))
 as
 begin
     declare @comment table --定義表變量
     (
     RowGuid nvarchar(50) not null default NEWID(),
     ParentGuid nvarchar(50) null,
     CommentText nvarchar(200) null,
     CommentUserGuid nvarchar(50) null,
     CommentUserName nvarchar(50) null,
     CommentDate datetime null,
     ToUserGuid nvarchar(50) null,
     ToUserName nvarchar(50) null,
     PictureGuid nvarchar(50) null
     )
     declare @parentGuid nvarchar(50);--第一父表標識變量
 
     insert  into @comment 
     select d.*  from DemoComment d
     where d.RowGuid=@RowGuid--添加記錄到表變量
 
     --select @parentGuid=c.RowGuid from @comment c;
     set @parentGuid=@RowGuid;--初始化父表標識的值
     declare @count int;
     set @count=1;--初始化循環條件,默認為1,標識可以循環
     while @count >0
         begin
             insert  into @comment select * from DemoComment where  parentguid=@parentGuid;--增加一條記錄到表變量
             select @parentGuid=c.RowGuid from DemoComment c where  c.parentguid=@parentGuid;--修改父表標識的值
             select @count=COUNT(RowGuid) from DemoComment c where  c.parentguid=@parentGuid;--為循環條件賦值
         end
 
     select c.* from @comment c;
 end
 
 GO

執行該存儲過程有結果如下:

好了,現在可以再寫一個存儲過程調用“[dbo].[sp_GetCommnetsByRowGuid] ”一次取出所有評論:

 create procedure sp_GetCommentsAndReplys
 as
 begin
 declare @RowNumberMin int;
 declare @RowNumberMax int;
 
 select @RowNumberMin=MIN(t.RowNumber),@RowNumberMax=MAX(t.RowNumber)
 from (select ROW_NUMBER()over(order by d.commentdate) RowNumber,d.* 
 from DemoComment d 
 where ParentGuid is null or ParentGuid ='')t
 
 print @RowNumberMin;
 print @RowNumberMax;
 
 
 declare @comment table --定義表變量
     (
     RowGuid nvarchar(50) not null default NEWID(),
     ParentGuid nvarchar(50) null,
     CommentText nvarchar(200) null,
     CommentUserGuid nvarchar(50) null,
     CommentUserName nvarchar(50) null,
     CommentDate datetime null,
     ToUserGuid nvarchar(50) null,
     ToUserName nvarchar(50) null,
     PictureGuid nvarchar(50) null
     )
     
 while @RowNumberMin <=@RowNumberMax
 begin
     
     declare @CommentGuid nvarchar(50);
     
     --insert into @comment
     select @CommentGuid=  t.RowGuid
     from (select ROW_NUMBER()over(order by d.ParentGuid) RowNumber,d.* 
             from DemoComment d 
             where ParentGuid is null or ParentGuid ='')t
     where t.RowNumber=@RowNumberMin;
     
     insert into @comment
     exec  [dbo].[sp_GetCommnetsByRowGuid] @CommentGuid
     
     set @RowNumberMin=@RowNumberMin+1;
 end
 
 select * from @comment;
 end
 go
 exec sp_GetCommentsAndReplys

結果:

好了,功能已完成,之後可以考慮優化的事了。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved