2012-12-10 133 views
22

我有一個通用數據庫結構問題。在我的場景中,我碰巧使用了mongodb。MongoDB結構:單個集合vs多個較小的集合

我創建了一個應用程序,用戶可以上傳歌曲列表(標題,藝術家等),但不知道是否應該爲所有用戶提供一個songList集合,或者單獨的songList.user#collection每個用戶。用戶只能查詢與其相關的歌曲,因此用戶A將永遠不會知道用戶B的歌曲。

代碼示例:每用戶

db.songList.userA.find() 
{"title": "Some song of user A", "artist": "Some artist of user A"} 

db.songList.userB.find() 
{"title": "Some song of user B", "artist": "Some artist of user B"} 
  • 優點
    • 小集合的大小

      多個集合查詢

  • 缺點
    • 可維護性
      • 1000個用戶裝置1000點的集合

VS與所屬單個集合 '用戶' 字段

db.songList.find({"user":"A"}) 
{"title": "Some song of user A", "artist": "Some artist of user A", "user": "A"} 
  • 優點
    • 靈活地在用戶查詢,如果需要不斷arised
  • 缺點
    • 性能

我試圖建立一個親/ con list,但仍然在圍欄上。鑑於每個用戶的歌曲將彼此隔離,哪種方法更好?我主要關心的是維護和查詢性能。

在此先感謝。

+3

而不是擔心這樣的事情,建立*的東西*。你可能會發現通過構建它會發揮什麼效果,而不是擔心細節。 – SomeKittens

+0

同意@SomeKittens。也就是說,我會爲每個用戶執行一次操作,因爲更容易犯錯並將A的歌曲顯示給B.無論如何,如果/當我有足夠的用戶時,我會擔心優化。 –

+0

安全方面,每個用戶擁有一個集合,可以使用Mongodb的集合級訪問控制機制。通過這種方式,可以確保在數據庫級別一個用戶不會訪問他人的數據。 –

回答

8

MongoDB是在水平擴展很大。它可以在動態集羣中對集合進行分片,以生成一個快速,可排隊的數據集合。

所以擁有一個較小的集合大小並不是真正的專業人士,我不確定這個理論到了哪裏,它不在SQL中,它不在MongoDB中。分片的性能如果做得好,應該與查詢單個小數據集合的性能有關(開銷很小)。如果它不是,那麼你已經設置你的分片錯誤。

MongoDB在垂直伸縮方面並不是很好,正如@Sushant引用的那樣,MongoDB的ns大小在這裏將是一個嚴重的限制。引用沒有提及的一點是,索引大小和計數也影響ns大小,因此它描述的原因如下:

因此,如果每個集合都有一個索引,我們可以創建多達12,000個集合。 --nssize參數允許你增加這個限制(見下文)。

+0

我讀過[this](http://stackoverflow.com/questions/11514781/mongodb-performance-issue-single-huge-collection-vs-multiple-small-collections)這導致我相信我會看到一個重要的性能增益與多個較小的集合。你是否在說如果我在用戶字段中有一個帶有分片鍵的集合,我應該看到類似的性能增益? – Steven

+0

那裏有太多的未知數,無法確切地說明他爲什麼要獲得這些時間,查詢時間依賴於硬件,索引,數據,規範化等等。但是他確實注意到,當他有大量記錄時查詢速度很快,問題是他在他的指數中使用了少量的選擇性(價格低於100的類型記錄的數量很少),這導致我認爲他的指數對他的查詢來說不是那麼好。 – Sammaye

+1

是的,關於user_id之類的分片鍵(這裏有一點猜測,你應該真的真的會爲你的數據研究這個)會對包含user_id的查詢產生不錯的回報。然而,這不是完整的分片圖片,我會強烈建議你在這裏和谷歌之前做一些搜索,然後立刻想到user_id將解決你的分片問題。 – Sammaye

11

我會推薦NOT爲每個用戶分別收集。

閱讀documentation

默認情況下,MongoDB的具有每 數據庫約24,000命名空間的限制。每個命名空間爲628字節,默認情況下,.ns文件爲16MB,默認爲 。

與每個索引一樣,每個集合都計爲一個名稱空間。因此,如果每個集合有一個索引,我們可以創建多達12,000個 集合。 --nssize參數允許你增加這個限制 (見下文)。

請注意,每個集合有一定的最小開銷 - 一個 幾KB。此外,任何索引都需要至少8KB的數據空間,因爲 的b-tree頁面大小爲8KB。如果 是很多集合並且元數據被分頁,則某些操作可能會變慢。

因此,如果您的用戶超出命名空間限制,您將無法優雅地處理它。隨着用戶羣的增長,它的性能也不會很高。

UPDATE

由於@Henry劉在評論中提到。對於使用WiredTiger存儲引擎的Mongodb 3.0或更高版本,它將不再是限制。

docs.mongodb.org/manual/reference/limits/#namespaces

+0

感謝您的信息,但閱讀下一段描述如何使用--nssize可以達到此限制(最大.ns文件大小爲2GB)。因此,如果每個歌曲列表集合只有1個索引,理論上可以在接近2GB之前擁有240,000個集合。 (如果每集有兩個索引,這個限制幾乎減半)。 – Steven

+0

你顯然可以用任何你想要的方式建模。我所做的一切都是推薦一個優雅的方法:) –

+0

感謝您的輸入是非常有用的,閱讀此信息多個集合似乎並不必要,因爲我可以做我需要的一個集合,同時避免命名空間限制。 – Steven