2011-01-25 67 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