2012-02-01 60 views
4

我們正在採用MongoDB作爲新的解決方案,並且正在嘗試爲我們的需求設計最有效的數據模型,即關於數據項之間的關係。MongoDB海量關係的最佳數據模型

我們必須在用戶,項目和列表之間保持三種關係。用戶可以有許多項目和許多列表。一個列表將有一個用戶和許多項目。一個項目可以屬於許多用戶和許多列表。後者尤其重要 - 一個項目可能屬於可能數量龐大的列表:數千個,當然可能有數十個或數十萬個。未來可能甚至達到數百萬。我們需要能夠在兩個方向上導航這些關係:例如,獲取列表中的所有項目或項目所屬的所有列表。我們還需要解決方案是通用的,以便我們可以在需要時添加更多類型的文檔和關係。

因此,似乎有兩種可能的解決方案。首先是數據庫中的每個文檔都有一個由「ID」數組組成的「關係」集合。因此,列表文檔將具有包含所有項目的ID的項目的關係集合以及具有該用戶的單個ID的關係集合。在這個模型中,當一個項目屬於許多許多用戶或許多許多列表時,這些數組將變得很龐大。

第二個模型需要一個新類型的文檔,一個「關係」文檔,存儲每個合作伙伴的ID和關係名稱。這會整體存儲更多數據,因此會影響光盤空間。它在NoSQL中看起來像是一種「非自然」的方式來解決這個問題。

性能明智,空間明智,架構明智,這是更好的,爲什麼?

乾杯, 馬特

回答

7

這取決於你的訪問模式。

  • 嵌入式ID數組更適合閱讀。通過快速閱讀,您可以獲得所有相關對象的ID,現在可以訪問並獲取它們。但是如果你的更新率很高,你就會遇到一些麻煩,因爲mongodb不得不一遍又一遍地複製同一個(已經很大)的對象,因爲它超出了它的磁盤邊界。

    但是這個解決方案是確實是寫入不好。想象一個屬於幾百萬個列表的項目。您決定刪除它。現在,您必須遍歷所有這些列表,並從參考數組中提取該項目的ID。這很令人興奮,不是嗎?

  • 將引用存儲爲單獨的文檔對寫入有好處。添加,編輯和刪除新引用非常快。但是這個解決方案需要更多的磁盤空間,更重要的是珍貴的RAM。閱讀速度並不快,特別是如果你有很多參考文獻。

    考慮到你的號碼(「未來可能會有數百萬人」),我會用這個解決方案。您可以隨時引入一些硬件來加速查詢。縮放寫入傳統上是最難的部分,在此解決方案中寫入速度快且可分片。

+0

感謝您的全面回答。我將嘗試使用數組,因爲讀取速度比寫入速度更重要,更新問題可以在代碼中獲得(我們不需要更新關係,因此可以繞過它們)。 – 2012-02-02 11:13:16

1

我同意Sergio關於數據訪問模式的關鍵。

我還要添加額外的可能的解決方案來存儲具有三個屬性的第四個文檔類型 - 對每個用戶,列表和項目的引用。該集合可以被索引以在所有3個字段上快速訪問,在所有字段上唯一索引以防止重複,並且允許快速插入和刪除。

最終,您不是以這種方式存儲更多的數據,因爲如果您需要從雙方查詢關係(「此用戶具有哪些項目列表?」和「哪些用戶在其列表中有此項目?「)你需要重複參考。

它感覺關係,但有時這是最好的解決方案。

+0

「感覺關係」 - 關係沒有什麼不對:-) – 2012-02-01 17:21:55

+0

當然不是:-) – 2012-02-01 17:23:02

+0

我不認爲我們可以這樣做,因爲我們必須對新的數據類型和關係開放,並且這會硬化我們開始進入模型。 (還是)感謝你的建議。 – 2012-02-01 17:23:56