2011-01-25 105 views
3

爲了提高性能,我有興趣從關係數據庫遷移到MongoDB。我將在多個位置存儲冗餘的非規範化數據,並且想知道是否有可能在沒有應用程序代碼的情況下自動維護數據的完整性。MongoDB - 自動維護數據完整性

舉例來說,如果我有一個用戶文件...

User: { _id: "...", userName: "johndoe", displayName: "John Doe", TotalTasks: 3 } 

然後一個任務文件...

Task: { _id "...", title: "Finish Reports", userID: "...", userName: "johndoe", userDiplayName: "John Doe" } 

我怎麼能自動保證該用戶名和顯示名保持不變在適當的文件中?如何確保在爲此用戶添加或刪除新任務時更新TotalTask​​s?

+1

您應該根據NoSQL原則重新設計您的模式。如有可能,應將任務嵌入用戶文檔中。我不認爲你接受你的問題的答案實際上適當地回答了它。 – 2012-03-19 11:02:26

回答

4

您無法在服務器端強制執行這些約束。然而觸發器是planned。目前支持的唯一約束是唯一索引。

+0

我希望有更像自動更新物化視圖的東西......就像CouchDD的工作原理一樣。我想這是我能找到的最佳解決方案。 – 2011-02-10 02:50:52

0

無法在沒有外部應用程序編碼的情況下使用MongoDB強制執行它們。上面的問題之一就是爲什麼沒有任務成爲用戶文檔的一部分?這將消除您的一致性問題,因爲您可以以原子方式處理用戶和任務。

但是,假設你不行,我過去所做的是使用MySQL和版本字段來強化一致性。每個應用程序都不同,但基本要點如下:

1)Mongo中的每個doc在MySQL中都有相關的行。 2)確定需要鎖定的文檔,然後在mysql中創建可序列化的事務。2)確定需要鎖定的文檔,然後在mysql中創建可序列化的事務。 3)使用查找和更新來更新mongo中的記錄,並確保版本字段匹配以強制執行樂觀併發。 4)如果一切都完成了,那麼在mysql中提交事務。 5)如果出現問題,回滾完成的所有mongo操作。如果回滾無法完成,則將信息推回​​到消息隊列中並具有「清理」的單獨進程。 6)回滾mysql事務

這必須謹慎使用,因爲它會爲您的操作增加很多開銷,但是,如果您按照我所描述的用戶 - >任務嵌入文檔,您應該會發現除了在某些外部情況或批量更新之外,您並不需要使用此功能。

+0

快速提問:如果您要使所有任務成爲用戶文檔的一部分,那麼這是否意味着每次需要用戶的屬性(而不是實際的任務)時,例如當您想要將用戶電子郵件地址發送一封電子郵件,這不會導致大量開銷,因爲Mongo將獲得整個文檔,包括可能的數千個任務?甚至只是對它執行查詢? – o1iver 2011-01-28 06:53:20