2011-03-18 52 views
8

我想使用MongoDB,C#和NoRM來處理一些示例項目,但是現在我有更多的時間圍繞數據模型進行包裝。使用RDBMS的相關數據是沒有問題的。然而,在MongoDB中,我很難決定如何處理它們。MongoDB,C#和NoRM +非規範化

讓我們以StackOverflow爲例......我沒有理解,一個問題頁面上的大多數數據應該包含在一個文檔中。標題,問題文本,修訂,評論...在一個文檔對象中都很好。

哪裏開始變得朦朧是用戶數據喜歡的用戶名,頭像,信譽(更改尤其常見)的問題...你非規範化和更新數以千計的文件記錄每次有用戶改變時間或者你以某種方式將數據鏈接在一起?

什麼是最有效的方式來完成用戶關係,而不會導致每次頁面加載時發生大量的查詢?我注意到NoRM中的DbReference<T>類型,但尚未找到使用它的好方法。如果我有可空的可選關係怎麼辦?

感謝您的洞察!

+0

+1,我想知道同樣的事情。 – jgauffin 2011-03-18 14:56:33

回答

1

我認爲你需要取得平衡。

如果我是你,我只是在每篇文章中引用userid而不是他們的名字/聲望。

雖然與RDBMS不同,但您可以選擇在文檔中嵌入註釋。

+0

我同意。我喜歡使用DBRef,因爲用戶數據易於頻繁更新。另一方面的評論在文檔中是完全可以接受的。 – jocull 2011-04-05 15:13:37

1

爲什麼你想避免非規範化和更新'成千上萬的文檔記錄'?爲非規範化而設計的Mongodb db。 Stackoverlow在後臺處理數百萬個不同的數據。有些數據可能會在短時間內陳舊,並且沒關係。

所以上述的主要思想是,你應該有非規範化的文件,以便快速顯示他們在UI。

無法以任何方式查詢引用文檔,您需要非規範化。

另外我建議看看cqrs架構。

+0

這不是我想避免非規範化,但我想避免固有的不良設計。從用戶記錄中分離一些常見的東西,我可以每秒更新數千條用戶記錄,這一點似乎是1.像過度使用一樣2.像磁盤空間使用不當一樣。沒有其他選擇嗎? – jocull 2011-03-18 15:56:37

+0

這取決於你想要的東西:如果你關心'磁盤空間'和反規範化,就像你對我的回答可能不是你的,但是如果你關心性能,你想達到你的速度 - 比你應該去上面描述的辦法。 – 2011-03-18 16:03:04

+2

更何況,磁盤空間*便宜* – 2011-03-18 18:26:28

2

我發現的餘額是使用SQL作爲規範化數據庫,Mongo作爲非規範化副本。我使用ESB來保持它們彼此同步。我使用了一個概念,我稱之爲「準備好的文檔」和「存儲的文檔」。存儲的文檔是僅保存在mongo中的數據。對於非關係數據很有用。準備好的文檔包含可以使用規範化數據庫中的數據重建的數據。它們以某種方式充當活動高速緩存 - 如果數據不同步(在複雜的文檔中這是一個昂貴的過程,因爲這些文檔需要重建許多查詢),可以從頭開始重建。他們也可以一次更新一個字段。這是服務總線進入的地方。它響應在規範化數據庫更新後發送的事件,然後更新相關的mongo準備文檔。

使用每個數據庫,以他們的長處。允許SQL成爲確保數據完整性的寫入數據庫。讓Mongo成爲快速發展的只讀數據庫,它可以包含子文檔,因此您需要更少的查詢。

**編輯** 我只是重新讀你的問題,並意識到你實際上要求什麼。如果有幫助,我會離開我的原始答案。

我將處理您給出的Stackoverflow示例的方式是在每個註釋中存儲用戶標識。你會加載其中會有所有註釋的帖子。那是一個查詢。

然後,您將遍歷註釋數據並提取需要加載的用戶標識數組。然後將這些加載爲批量查詢(使用Q.In()查詢運算符)。這兩個查詢總數。然後,您需要將數據合併到一個最終表單中。您需要在這種情況下執行此操作,以及何時使用類似於ESB的操作來手動更新每個文檔。使用最適合數據結構的每個單獨場景的方法。

+0

我喜歡這個解決方案。加載一批用戶ID然後組裝數據是個好主意。 – jocull 2011-09-17 04:48:10