MongoDB数据完整性

时间:2018-03-08 15:29:26

标签: database mongodb

我是MongoDB的新手,最难理解的是如何确保数据的完整性。

我有两个收藏帖子 - >评论(一对多)。

有没有办法为每个帖子存储评论数量,而不使用two phase commit

Post {
    _id,
    text,
    commentsNumber
}

Comment {
    _id,
    text,
    postId
}

添加/删除评论时,commentsNumber必须递增/递减。这是对两个不同集合的两个请求。例如在MongoDB中,写操作在单个文档的级别上是原子的,有可能添加/删除注释,但是commentsNumber不会被更新或反之亦然。

保证诚信的技巧是什么?

  • 每个时间段运行脚本以更新commentsNumber
  • 根本不存储commentsNumber

2 个答案:

答案 0 :(得分:2)

我怀疑除了上面提到的两阶段提交之外,还有什么能够保证数据完整性。至少到announced v4

几乎没有什么可以减少错误计数的可能性。 将插入和更新合并为一个bulk。它将减少其中一个操作在应用程序端失败的可能性,因为它是单个请求。

然后检查nInserted === 1nModified === 1。否则,请为给定的帖子ID重新尝试或排队重新计算作业。

对于重试,必须启用retryable writes,因为您将在帖子上使用$inc,这与幂等操作相距甚远。

另一种选择是应用transactionless方法 - 一种“每个时间段运行脚本以更新commentsNumber”和“根本不存储commentsNumber”的组合。您需要保留上次重新计算作业的时间戳,并计算自该日期以来的新注释。

答案 1 :(得分:1)

由于您提到在帖子中嵌入评论不是您的用例的可行选项,并且不想进行2阶段提交,

我可以考虑以下选项:

  1. 在Comment集合的postId属性上创建二级索引。最后在Comment集合上使用基于postId的count(...)函数。

  2. 另一个选项是让map-reduce作业在每次添加评论文档时将commentCount和postId存储在新集合中。

  3. 在这两个选项中,您不需要在Post文档中存储commentNumbers。需要注意的一点是,由于commentsCount不是Post文档的一部分,这将导致mongo的新查询读取计数。