【问题标题】:MongoDB - Maintain data integrity automaticallyMongoDB - 自动维护数据完整性
【发布时间】:2011-06-15 12:21:06
【问题描述】:

我有兴趣从关系数据库迁移到 MongoDB 以提高性能。我将在多个位置存储冗余的非规范化数据,我想知道是否可以在没有应用程序代码的情况下自动维护数据的完整性。

例如,如果我有一个用户文档...

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

然后是任务文档...

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

如何自动确保相应文档中的 userName 和 displayName 保持不变?当为此用户添加或删除新任务时,如何确保更新 TotalTask​​s?

【问题讨论】:

  • 您应该根据 NoSQL 原则重新设计您的架构。如果可能,应将任务嵌入到用户文档中。我认为您接受的问题的答案实际上并没有恰当地回答它。

标签: mongodb


【解决方案1】:

如果没有一些外部应用程序编码,则无法使用 MongoDB 强制执行它们。我会在上面提出的一个问题是,为什么不让任务成为用户文档的一部分?这将消除您的一致性问题,因为您将能够原子地处理用户和任务。

但是,假设你不能,我过去所做的是使用 MySQL 和版本字段来强制一致性。每个应用程序都不同,但基本要点如下:

1) Mongo 中的每个文档在 MySQL 中都有一个相关的行。 MySql 中的这一行将包含集合、文档的 id 和一些审计信息(上次更改、谁更改等) 2)确定您需要锁定哪些文档,然后在 mysql 中创建一个可序列化的事务。 3) 使用 Find and update 更新 mongo 中的记录,并确保版本字段匹配以强制执行乐观并发。 4)如果一切都完成了,那么在mysql中提交事务。 5) 如果出现问题,回滚 mongo 中已完成的所有操作。如果无法完成回滚,则将信息推送到消息队列中,并有一个单独的进程来“清理”。 6)回滚mysql事务

必须谨慎使用它,因为它会为您的操作增加很多开销,但是,如果您按照我在 user -> 任务中描述的那样嵌入文档,您应该会发现您实际上并不需要使用它某些外部情况或批量更新除外。

【讨论】:

  • 快速问题:如果您要将所有任务都作为用户文档的一部分,这是否意味着每次您需要用户的属性(而不是实际任务),例如当您想要获取用户的电子邮件地址以发送电子邮件,这不会导致显着的开销,因为 Mongo 将获取整个文档,包括可能 1000 个任务?或者甚至只是对其执行查询?
  • 如果这是一个问题,我猜您可以只将所有任务的对象 ID 存储在用户文档中,但是您需要执行两个查询才能为某个用户获取某个任务。 ..正确的? (我很可能在这两种情况下都错了,因为我刚刚玩过 Mongo)
【解决方案2】:

您不能在服务器端强制执行这些约束。但是触发器是planned。当前支持的唯一约束是唯一索引。

【讨论】:

  • 我希望有一些更像自动更新物化视图的东西......就像 CouchDD 的工作原理一样。我想这是我能找到的最好的解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-06-21
  • 1970-01-01
  • 2021-09-21
  • 2020-08-04
  • 1970-01-01
  • 2010-09-24
  • 2011-11-26
相关资源
最近更新 更多