搜尋

首頁  >  問答  >  主體

数据库设计 - mongodb文章和评论放在同一条数据里效率怎样?

将评论和文章放在一起,这里我有一个疑问,当评论数量很大以后,会不会导致在查询文章列表页的时候效率低下?
如果将comments剥离到另一个collection里,这样是不是能缓解只显示文章列表的情况下的压力

{
	"_id" : ObjectId(),
	"author" : "",
	"comment_num" : "",
	"comments" : [
		{
			"text" : "",
			"created" : ISODate(),
			"author" : ""
		},
	],
	"created" : ISODate(),
	"text" : "",
	"title" : ""
}
黄舟黄舟2765 天前629

全部回覆(2)我來回復

  • 大家讲道理

    大家讲道理2017-04-21 10:59:50

    @halty 說得很好,不完全同意他的觀點。如果評論不多,放在一起的設計很合適,樓上說得很好。但是如果評論多了,問題就來了。最重要的有兩基本出發點: 1. 硬碟太慢; 2. 只要資料在記憶體裡,就沒問題。

    1. find
      數據特別大了之後,在磁碟上讀好多數據,因為Memory Mapped File都會放在內存裡,可是我們只需要裡面的一小部分,最主要的問題是可能OS會把別的數據換頁到硬碟上。光就列出文章列表來說,記憶體就沒有被有效利用。
    2. insert
      在磁碟檔案上,如果一個document一直長啊長,好多次,這不是好事。因為 如果新加入資料後,例如加了一個新評論,document變大了,原來的地方放不下了,就要找新的地方,以前的空洞會被重新利用。但問題是,document位置變了,所有跟它有關的索引都要變。如果你還有陣列上的索引,像是發表評論的用戶名,那麼更新的索引就跟這個陣列長度成線性關係。
    3. size
      樓上在這點說得很好。 16MB的上限。

    綜上,評論特別多的時候,會影響性能。

    總結,schema設計要考慮

    1. 資料規模,經常存取的資料只要在記憶體裡,對存取來說沒什麼問題。上面第一條find裡提到的記憶體利用不充分,其實不是大問題。因為熱門文章的評論總有不少人看,放內存裡也不錯。如果document一直長呀長,MongoDB會自動地在分配磁碟空間時多分配一些。
    2. 與Access Pattern相適應。寫評論相對看文章看評論,太小了,Twitter的數據是平均發tweet 5K/s, 讀timeline 300K/s. 60倍呀!只要讀取請求在記憶體裡能滿足就好了。用MongoDB就可以不用另搞caching了。不是訪問真得特別大,寫特別多這樣極端的情況,都好說。真是得到了那一天,MongoDB的sharding就派上用場了。
    3. 開發方便 產品的成本不只是機器硬體、網路的成本,更重要的是程式設計師的開發成本,薪水都那麼高……所以,寫著快速方便,不容易出錯也是很重要的一點,對不?這也解釋了為什麼MongoDB文件模型的彈性廣受好評了。

    話說回來了,我覺得絕大多數這類應用的評論都不會過百吧……這時候單文檔就發揮出優勢了,幾百評論都沒問題的,題主的問題就不是問題了。希望題主的應用能突破這個數字…

    回覆
    0
  • ringa_lee

    ringa_lee2017-04-21 10:59:50

    首先確認一點:當評論數量很大以後,不大會導致在查詢文章列表頁的時候效率低下。你可以再指定查詢結果集的document只傳回部分field的資料(需要注意的是,如果對這種只包含部分field資料的document進行更新再儲存時,有可能會出錯),推薦這樣做,能夠很好的節省網路頻寬。

    此外,目前mongodb對於單一document的大小是有限制的,如果評論數量過多時,會有可能超過document的預設大小限制,這個時候就需要剝離comment了。

    回覆
    0
  • 取消回覆