2010-09-28 89 views
21

我正在建立一個簡單的會計系統,用戶有很多賬單。現在我正在試圖確定賬單應該是自己的收藏,還是嵌套在用戶中。我傾向於前者,但我從來沒有做過任何noSQL的東西,所以我只是通過試驗和錯誤,我認爲對我有意義。Mongo DB設計,嵌入vs關係

據我所知,Mongo的文件大小限制爲4mb,這讓我覺得我應該有一個單獨的帳單收集,因爲這些將每天累積,最終可能會佔用大量的空間。

我只是找對此事的意見。基本上我會在不同的日期間查詢用戶帳單(正如你可以想象會計系統會這樣做)。

不在於它真的很重要,但我在Rails3中項目中使用Mongoid。我想我會這樣做:

class User 
    references_many :bills 
end 

class Bill 
    referenced_in :user 
end 

任何意見或設計建議,非常感謝。你可能要考慮

回答

24

1)關於4MB文件的限制,這是什麼「的MongoDB權威指南」說:不是4MB大

文件(當轉換爲BSON)不能被保存到數據庫中。這是一個有些武斷的限制(將來可能會提出);主要是爲了防止糟糕的模式設計並確保一致的性能。爲了從殼中看到的文檔DOC的BSON大小(以字節爲單位),運行Object.bsonsize(DOC)。

爲了讓你知道4MB是多少,戰爭與和平的全文只是3.14MB。

最終它取決於您期望用戶增長的賬單有多大。我希望上面的摘錄能夠讓您瞭解文檔大小所帶來的限制。

2)如果你知道你永遠不會在賬單上運行全局查詢,那麼非標準化的模式(賬單隨用戶文檔一起)就是要走的路(這樣的查詢的例子是如果你想檢索進入系統的最近十張賬單)。如果使用非規範化模式,則必須使用map-reduce來檢索此類查詢的結果。

如果您希望查詢賬單的方式具有靈活性,則規範化的模式(用戶和單獨單據中的賬單)是更好的選擇。但是,由於MongoDB不支持連接,因此每次要檢索與用戶對應的賬單時都必須運行多個查詢。

鑑於你提到的用例,我會去解規範化的模式。

3)MongoDB中的所有更新都是原子序列化的。這應該回應史蒂夫的擔憂。

您可能會發現這些幻燈片很有幫助。 http://www.slideshare.net/kbanker/mongodb-meetup

您也可以看看MongoDB的Production Deployments頁面。您可能會發現SF.net幻燈片很有幫助。

+0

啊它只是在寫...這是否會影響嵌入式文檔的原子選擇?例如,如果我只是在我的用戶文檔中對我的賬單進行$推送,那麼,如果我的用戶和所有賬單達到4mb,或者只有賬單本身在寫入時爲4mb纔算是否重要。我有一種感覺,它是後者,因此我很安全(因爲單一賬單不可能包含4mb數據,或者我會在1次寫足夠的賬單以達到這個數量)這聽起來是對的嗎?假設,我想我會採取你的建議,並去標準化。 – brad 2010-09-28 23:30:50

+0

嗯...我想我其實是錯的,我敢肯定如果他們的賬單超過了這個數額,4mb限制會影響用戶,但是賬單中的數據量相當小,所以我要給它一張帶嵌入式賬單的照片,並在未來做一些測試,看看我可以處理什麼樣的賬單容量 – brad 2010-09-29 12:11:59

1

一個問題是,會不會有永遠是一個時間,你需要從他們的成員單獨分開引用賬單用戶?如果是這樣,如果他們有獨立的存在就會更簡單。

除此之外,你已經確定的大小限制的問題是一個很好的理由分裂他們。

有可能是一個交易的問題爲好,如果你正在寫了許多包括票據龐大的用戶,如果你改變的合理同時寫入不同的連接相同的用戶會發生什麼?我對mongo知之甚少,不知道它會如何解決這個問題 - 我的猜測是,如果寫入內容包含不同的附加賬單,您可以同時獲得這兩個賬單,但如果它們包含現有賬單的不同更改,則會被覆蓋 - 希望別人會對此發表評論,但至少我會測試它。如果您將帳單寫入單獨的收藏夾,這不是一個問題。

1

由於這個問題已經解決了很長時間,但我正在處理類似的事情,並認爲我會將我的發現添加到研究此問題的任何其他人。

我的理解是,4MB文檔在版本1.8+中已擴展到16MB。這是來自MongoDB成員之一Banker的視頻介紹。我沒有驗證這個價值,但是他接受了他的話(因爲他希望知道他在說什麼)。

至於當同一個用戶使用嵌入式賬單發生多個更新時,會發生什麼......如果再次使用同一個視頻演示文件,問題就在於MongoDB更新信息的速度太快,通常不是問題。在更新發生時,MongoDB實例被鎖定,所以多個更新不應該成爲問題。

我對嵌入式文檔的一個擔憂是它們不能獨立於其父文檔處理。在我看來,這使得嵌入式文檔變得毫無價值。它們僅適用於滿足特定用例的利基案例。

我個人發現MongoDB(和NoSQL DB)在特定情況下很有用,但傳統的SQL/RDMS對於大多數問題仍然更好。如果你是Craigslist之類的人,並且模式變更需要2個月時間來運行你的歸檔數據,那麼是的,MongoDB和NoSQL是合理的。但對於絕大多數應用程序,我不認爲處理這些數據量是一個主要問題。