2012-03-18 246 views
1

我有一個應用程序顯示帖子,並且對於每個帖子,用戶可以說他們是否喜歡該帖子。 對於每篇文章,我應該顯示有多少用戶喜歡它,有多少人不喜歡它。 假設我有這些表:SQL Server:表設計中的幫助

CREATE TABLE [dbo].[Post](
[Id] [bigint] IDENTITY(1,1) NOT NULL, 
[Quotation] [text] NOT NULL, 
CONSTRAINT [PK_Post] PRIMARY KEY CLUSTERED 
(
    [Id] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,  ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] 

CREATE TABLE [dbo].[UserPostAction](--Every action of the user (like or dislike) is  recorded to this table 
[PostId] [bigint] NOT NULL, 
[UserId] [bigint] NOT NULL, 
[ActionValue] [int] NOT NULL, --Like/Dislike 
CONSTRAINT [PK_UserPostAction] PRIMARY KEY CLUSTERED 
(
[PostId] ASC, 
[UserId] ASC,  
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,  ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 

什麼是最好的方式,性能明智的,有一個返回帖子列表包含喜歡/不喜歡的統計數據已經在select語句:

A)向Post表中添加2列:TotalLike和TotalDislike,當向UserPostAction插入新記錄時,我將更新這些列?這樣,從Post表中選擇帖子時,我將獲得已計算的統計數據。 B)添加第三個表格:PostStat([PostId],[TotalLike],[TotalDislike])並在批處理過程中更新表格。 select語句將使用Post.Id = PostStat.PostId上的Inner Join來檢索統計信息。 C)任何你能想到的其他方式。

希望我有一個擁有數百萬帖子的數據庫,並且Post表會被很多用戶頻繁查詢。 請記住,統計信息的更新頻率非常高,因爲很多用戶會喜歡或不喜歡很多帖子。它意味着(可能)執行很多更新和表鎖定,這會干擾返回要顯示的帖子的select語句。

任何想法是值得歡迎的。

+0

如果您一次更新單個帖子,不應該有任何表鎖定的風險。還有什麼原因你使用文本vs(n)varchar(max)數據類型? – etliens 2012-03-18 18:47:31

回答

1
I will have a DB with millions of posts 

不認爲這是足夠的理由保持對你的數據庫的重複數據。

您已經擁有了您當前所需的所有信息。它是構建正確索引的問題,您可以輕鬆計算有多少用戶喜歡\不喜歡該帖子。

如果你真的不符合這種方法,我建議在UserPostAction表上使用觸發器來實現選項A來維護你的2個新列。

+0

在每個「獲取」上從UserPostAction表中計算喜歡/不喜歡的內容不會很好地擴展。 – etliens 2012-03-18 17:42:24

+0

這是一個非常模糊的陳述。我可以或不可以基於幾個因素,而我們真的不能基於他給我們的信息量(這只是一個,真的)得出結論。這就是爲什麼我給了2個選項 – Diego 2012-03-19 01:24:17

+0

你需要更多信息嗎? – kruvi 2012-03-19 06:20:14

1

我遇到類似的情況,我選擇策略答:

  • 把以主表中的信息是給定的,你必須張貼間的一種一對一關係「正常」的選擇和PostStat。
  • 每次查詢帖子時,您都不必在Post和PostStats表之間進行連接,我認爲這比訪問包含分散在兩個列中的相同列的單個表更加昂貴。
  • 如果你用觸發器更新喜歡/不喜歡的計數器(這就是我所做的),讓父表上的列將使生活變得如此簡單......事實上,你只需要編寫一個「更新後設置喜歡=喜歡+ 1其中postId =:new.postId「(oracle sql語法),並且對postId的引用完整性將保證你有一行更新。

知道寫入不會阻止讀取(事實上,他們只會讀取以前的值,直到事務完成)我懷疑您將鎖定問題放在主表上的列。