像知乎這樣的評論回復模式,資料庫應該怎麼設計比較好,考慮性能、可擴展性等?

知乎允許所有用戶對問題和答案進行評論,同時所有人可以對所有評論進行回復,且回復可嵌套進行


像知乎這樣的線性評論,設計如下即可滿足:

Comment:

{

id, //評論唯一id

owner_user_id, //發表評論的用戶id

target_user_id, //評論的目標用戶id

content, //評論內容

likeCount, //該評論被點贊的數量

created_at, //創建時間

parent_id, //評論的目標id

parent_type //評論的目標類型

}

考慮到性能問題:

我會用mongodb,在針對mongo蛋疼的索引的查詢上(如果項目確定好了只有那麼幾個查詢條件,那就不蛋疼),數據結構中需要加入一個Array類型的data欄位,該欄位保證所有的Comment的數據都在其中,用key-value的形式保存,這樣查詢時根據data中的key和value查,整個表的索引就只需要加在data上

(這一段我說的很簡單,實際操作起來相當複雜)

考慮到可擴展性(用mongodb的話,不用刻意管理表結構的變化,直接增添欄位即可):

1. 對評論進行點討厭?

表結構加入:dislikeCount //該評論被討厭的數量

2.對評論展現出該評論被評論的數量?

表結構加入:commentCount //該評論被評論的數量

3.評論可以發表圖片?

表結構加入:photo_id //關聯photo對象,其中有id, url, filename, 等等

4.評論可以修改?

表結構加入:updated_at, //修改時間

5.評論可以評分?

表結構加入:rate //評論的評分等級

6.評論還需要更多屬性?

表結構加入custom_fields //Object類型,任意json形式key-value自定義數據

以上,所有設計來自於一年前做這個的設計與開發。

Arrownock 文檔中心

如果是樹狀評論呢?

有人看再說。


謝邀。評論學Disqus就好了嘛 Scaling Threaded Comments on Django at Disqus

知乎資料庫結構全是anti pattern吧,畢竟是能出現-1條評論的資料庫設計。


CommentID: GUID (primary key)

UnderWhichAnswer: GUID (index + foreign key)

ReplyWhichComment: GUID (nullable + foreign key)

Author: GUID (foreign key)

Time: datetime (ascend)

Content: string

然後按照UnderWhichAnswer全部query出來,按照Time或ReplyWhichComment在客戶端排序,看你使用什麼View。

==========================================

總覺得這個答案寫出來不久,知乎就實現了這個功能了啊,先按頁排序,然後tree給做到了另一個頁面里擼成了list,跟我的評論有異曲同工之妙。


資料庫怎麼設計按SQL Server來說的話。

首先有一張問題表,主鍵自增ID,參考知乎URL(/question/38959595) 這裡的ID就是自增主鍵,唯一表示這個問題。包含標題,標籤組ID集,聚集索引加在主鍵上

----------------------------------------------------------------------

QuestionID Title TagGroup -&> Other functional columns

----------------------------------------------------------------------

38959595 xxx 131,231,441,21

----------------------------------------------------------------------

38959594 xxx 142,11

----------------------------------------------------------------------

接著做一張回答表,包含問題主鍵,回答副主鍵,格式應該為38959595 1, 38959595, 2,在這兩個列上建立主鍵,創建聚集索引。 回答表上創建Vote+, Vote - , 贊同user list關聯表,其與相關功能列

----------------------------------------------------------------------

QuestionID AnswerSubID Vote+ Vote - Content

----------------------------------------------------------------------

38959595 1 18 2 aaaa

----------------------------------------------------------------------

接著做一張回復表,回復表包含問題主鍵,回答子鍵,回復子ID,和父回復ID 表示回答某個回復。 聚集索引創建在QuestionID, AnswerSubID, RepSubID

大概為這樣

----------------------------------------------------------------------

QuestionID, AnswerSubID , RepSubID, RepParentID

----------------------------------------------------------------------

38959595 1 1 -1

----------------------------------------------------------------------

38959595 1 2 1

----------------------------------------------------------------------

38959595 1 3 1

----------------------------------------------------------------------

其中第一條為回復A,2,3條為對回復A的評論

以上設計中標籤組ID集使用string鏈接Tag的方式來為了簡單化設計,你也可以為Tag單獨建立一個表,引用內容主鍵。

贊的用戶集合需要單獨設計一張表來存儲,包含被贊的問題主鍵,回答副鍵,和回復副鍵可用作回答和回復的點贊用戶統一使用,判斷回復副鍵是否為NULL來觀察贊的那種類型的數據。

分組

-----------------------------------------

接下來表設計粗略完成。這三個大表組完RAID以後分別放入不同的磁碟陣列中,為提高IO性能。

磁碟性能優先順序應主要考慮 答案》回復》問題。

為問題建立 partition 最好按天來創建,因為內容是每天獲取熱點數據,後台service在組建熱點問題演算法存入資料庫後,按此熱點度量值進行熱點問題ID集合提前到內存中最好。

這只是非常簡單的設計,大多數功能並沒列在表設計中,要達到高性能還需要自己摸索存儲過程中事務並發控制和隔離級別的設計。不要一味的進行反模式設計,畢竟實踐出真知。不要看不起SQL Server性能。工具都一樣,只有好的程序員和差的程序員之分。


知乎為了優化資料庫也是拼了

(逃


瀉藥。回復不是嵌套的啊。

很容易設計啊。

Reply {

id

content

user

father_reply_id (可以空)

}


不要像知乎這樣設計就好


我到現在都不知道怎麼在手機看別人回復我的評論的消息,評論太多找不到我評論別人時被其它人回復的


知乎的comments就是個線性結構,估計是嫌麻煩所以沒做成樹狀結構吧,回復的其實是「用戶」而不是「評論」,這樣就可以不要父子關係,也不用考慮萬一父結點刪掉了子結點該怎麼辦得問題。

======================

這幾天知乎更新了,評論區加入了分頁功能,看來我的估計是沒錯的,知乎的做法其實就是BBS里最常見蓋樓的做法,只是略有改動。

首先,帖子是按照時間排序的,帖子里有「作者」和「回復某人」這兩個欄位,如果需要查看某條會話線索,只需把某兩個人互相回復的帖子拉出來即可。

這麼做其實挺省事,效率也高,比搞成個樹不知道好到哪裡去了,反正你也不是真的需要一棵樹。


、同求


測試回復


我是一隻菜鳥戰鬥機,設計過評論功能。我也不知道是樹狀還是什麼線性,用的是父子ID形式,父級刪除的話邏輯上也會把子級刪除,如果有下下級(這貌似就煩了~)。主要是很擔心一個問題,想uc的評論(百度貼吧就先算了),熱門文章都是幾千幾萬的評論,再加上回復(先不考慮下下級),需要多少數據行,數據會非常恐怖吧?nosql我也是剛知道,這個資料庫是否在處理這個問題上有很大優勢?請大神指教。另外,json類型的是否合適


感覺跟微信的評論一樣的,只要分為兩種情況,評論的接受id為空,為回復答主,評論不為空,回復的特定的人。分頁按發布時間排序,輕鬆搞定。當然這不是樹展開的。


剛才特意又去評論了下,沒有樓中樓之類的東西,那就太簡單了,commentid,content,uid,to_uid。


分兩張表,一張主表記錄對答案的評論,一張子表記錄對評論的評論。


先讓它跑起來再說,先讓它跑起來再說,先讓它跑起來再說


我也在糾結這個問題


資料庫加個欄位保存用戶id不就解決了嘛


推薦閱讀:

SQL語句為什麼使用select * 會降低查詢速度?
單機 MySQL 資料庫可以支撐多大數據量?
關於資料庫,非空列有什麼好處嗎,和索引有什麼關係,為什麼盡量設置成非空呢?
如何寫一個輕量級分散式資料庫?
資料庫主從複製,讀寫分離,負載均衡,分庫分表分別表達的什麼概念?

TAG:Web開發 | 資料庫 | 程序員 | 資料庫性能 | 資料庫設計 |