2012-03-04 112 views
4

好吧,我在Mongodb中開發的越來越多,我開始想知道需要多個集合還是有一個帶索引的大集合(因爲每個文檔的列和字段可能與表格數據不同)。如果我試圖以最有效的方式開發(意味着更少的代碼和可重複使用的代碼),那麼我可以爲所有文檔使用一個集合,並且只需在一個字段上索引。通過將索引中的所有文檔放在一個集合中,我可以重新使用所有表單處理代碼和其他代碼,因爲它將全部插入到同一個集合中。MongoDB - 使用索引的一個集合

例如:

可以說我正在開發一個聯繫人管理器,我有兩種類型的聯繫人「個人」和「企業」。我最初的想法是創建一個名爲個人的集合,第二個集合稱爲企業。但那是因爲我習慣於在sql中進行開發,因爲這將是合適的,因爲每個表的列都是不同的。我越是開始思考文檔dbs的靈活性,我開始思考得越多,「我真的需要兩個集合嗎?」如果我只是將一個字段添加到每個稱爲「聯繫類型」和索引的文檔,我是否真的需要兩個集合?由於每個文檔中的字段/列不一定全部相同(比如在sql中),因此每個文檔都可以有自己的字段,只要我有一個「文檔類型」字段和該字段的索引即可。

那麼我接下這個概念,並開始思考,如果我只需要一個「個人」和「企業」集合,那麼我甚至需要爲「用戶」或「聯繫歷史記錄」或任何其他數據單獨收集。理論上,我無法在一次收集中構建整個解決方案,並且每個文檔中都有一個字段,用於指定「類型」和索引,如「用戶」,「個人聯繫人」,「業務聯繫人」,「聯繫人歷史記錄「等,如果它是一個文件相關的另一個文件,我可以在」父鍵/外部「Id字段索引...

這將允許我動態地編碼前端,因爲表單處理代碼會都是相同的(插入到同一個集合中)。這樣可以節省很多編碼,但是我想通過使用索引和二級索引來確保數據庫仍然能夠快速運行,並且隨着集合的增長不會導致未來的問題。正如你可以想象的那樣,如果一切都在一個集合中,隨着用戶基數的增長,這個集合中可能會有成千上萬甚至上百萬的文檔,但它會有索引和二級索引來優化性能。

我的問題是:這是mongodb開發人員使用的常用方法嗎?爲什麼或者爲什麼不?什麼是垮臺,如果有的話?如果這是一種常用的方法,請給出任何肯定使用這種方法。謝謝。

回答

-1

MongoDB和NoSQL一般來說是關於解規範化數據和減少連接。它違背了一般的SQL思想。

就你而言,我看不出有什麼理由讓你想要分開收集,因爲它會帶來不必要的複雜性和性能開銷。例如,考慮一下,如果你想有一個按字母順序顯示所有聯繫人的屏幕。如果你有一個單一的聯繫人集合,那麼它很容易,但如果你有兩個集合,它將變成一個更復雜的命題。

如果您的應用程序有多個用戶存儲聯繫人,我將擁有多個集合。然後,我會爲每個用戶提供一個集合。這使得提取用戶聯繫非常容易。

+0

是的,我會有多個用戶,但即使如此,我是否需要多個集合,如果我只索引集合名稱和用戶ID,然後減少/過濾用戶的會話ID結果。那麼我仍然只使用一個集合? – user982853 2012-03-04 18:15:07

+0

我知道cassandra是關於反規範化的,但其他許多實際上與SQL沒有任何不同(在這方面)。面向文檔的數據庫實際上只是組織數據庫的一種不同方式。當涉及到關係模式時,mongo也是非常寬容的 – kelloti 2012-03-04 18:29:07

2

這在Mongo中非常重要,答案更多的是藝術而不是科學。擁有一個充滿巨大文檔的集合絕對是一種反模式,因爲它與Mongo的許多功能相反。例如,當檢索文檔時,您只能從集合中檢索整個文檔(不完全正確,但大多數情況下)。所以如果你有大量的文件,你每次都要檢索大量的文件。另外,擁有大量文檔會使分片的靈活性降低,因爲只有頂級文檔在每個集合中被索引(因此分片)。您可以將值深入索引到文檔中,但索引值與頂層文檔相關聯。

與此同時,純屬關係也是一種反模式,因爲你首先去了Mongo就失去了很多參照完整性。而且,所有連接都在應用程序內存中完成,因此每個連接都需要完整的往返(慢速)。

所以答案就是在兩者之間做點什麼。我想在這種情況下你可能會想爲個人收集一個集合,併爲商家收集一個不同的集合。我這樣說是因爲它看起來像企業有足夠的元數據相關聯,它可以大量增加。 (另外,我個人與企業的關係看起來像是多對多)。但是,個人可能有Name對象(具有firstlast屬性)。把Name變成一個單獨的集合是一個壞主意。

一些信息從10gen的有關架構設計:http://www.mongodb.org/display/DOCS/Schema+Design

編輯

此外,蒙戈有交易的有限支持 - 在原子聚集體的形式。當您將對象插入到mongo中時,整個對象將被插入或未插入。所以你是應用程序域需要某些對象之間的一致性,你可能想要保持它們在同一個文檔/集合中。

例如,考慮需要一個User總是具有Name對象(含有FirstNameLastNameMiddleInitial)的應用程序。如果User以某種方式插入而沒有對應的Name,則數據將被認爲是損壞的。在RDBMS中,您將圍繞操作包裝UserName。在Mongo中,我們確保NameUser位於同一文檔(聚合)中,以實現相同的效果。

您的示例稍微不太清楚,因爲我不瞭解商業案例。有一點可以想到,Mongo對繼承有很好的支持。將所有用戶,個人和潛在業務放入同一個集合中(取決於應用程序的建模方式)可能是有意義的。如果一個人有很多聯繫人,那麼您可能希望個人擁有一組ID。如果您的應用程序要求您快速預覽聯繫人,則可以考慮複製個人的一部分並存儲一組聯繫人對象。

如果您習慣於RDBMS思維,那麼您可能認爲您的所有數據必須始終保持一致。事實是,這可能不完全正確。最近DDD社區大力宣傳將原子聚合應用於域的這一概念。當您深入瞭解您的域時,就像您的業務用戶一樣,一致性邊界應該變得截然不同。

相關問題