在 MongoDB 中模拟关系

Posted

技术标签:

【中文标题】在 MongoDB 中模拟关系【英文标题】:Simulating relations in MongoDB 【发布时间】:2011-03-02 01:54:06 【问题描述】:

作为最受欢迎的 NoSQL 解决方案之一,MongoDB 具有这种方法的大部分优势。但我仍在努力解决的一个问题是如何在 NoSQL 数据存储中反映对象关系,特别是 MongoDB。

例如,让我们考虑一个简单的数据模型:用户、帖子和评论。我很清楚 cmets 本身没有价值,因此成为 Posts 的嵌入对象。但是当涉及到用户时 - 这变得很棘手,因为用户本身就是一个实体,而不是与 Post 耦合。现在,如果我需要在网页上列出带有用户全名和个人资料链接的帖子,我需要有一个帖子列表和有关帖子作者的信息(至少名称和 ID)。

我在这里看到了 2 个可能的解决方案:

    以每个帖子条目包含其作者 ID 和全名(以及列出帖子时可能需要的任何其他用户属性)的方式对数据进行反规范化。这样,我可以使查询数据变得非常简单,但是当用户更新他/她的个人资料时,我也需要更新用户的所有帖子。但是我还需要在 cmets 对象中存储用户属性,这意味着更新用户配置文件本质上需要我更新所有至少有用户评论的帖子,除非我想将 cmets 存储在单独的集合中。 仅在帖子对象中存储用户 ID 并运行 2 个查询:一个用于获取帖子列表,另一个用于获取用户 ID 在帖子作者列表中的用户列表。这需要在我的应用程序代码中进行 2 次查询和额外处理才能将用户映射到帖子。

我确定我不是第一个遇到这个问题的人,但不幸的是,到目前为止,我还没有找到任何关于这个主题的最佳实践。意见?

【问题讨论】:

您使用了哪种方法架构?解决方案1?还是解决方案 2? TTT 的回答中对它的描述非常好 - 根据您需要从数据中获取什么,您需要进行选择。我在我的应用程序中实现了这两种方法。 只是好奇,你喜欢mongodb吗?您使用 mongo 的体验如何? 【参考方案1】:

两者都是有效的解决方案,解决方案 1 的优点是您可以显示这样的页面,只从数据库中检索一个文档。用户不会经常更新他们的个人资料,您可以在更改用户个人资料后异步更新所有帖子和嵌入式 cmets。您可以索引用户 ID 上的帖子和嵌入的 cmets,因此更新应该很快。在 mongodb 中更新非常快速,因为 mongodb 会进行就地更新,并且您无法回滚或提交,因此 mongodb 不必记录更改。

但是,像 *** 这样的网站上的用户也有声誉,而且这种声誉的变化比他们的个人资料要大得多。

解决方案 2 需要每页检索更多文档,但是您可以将 $in 运算符与用户 ID 列表(post 的用户 ID + cmets 的用户 ID)一起使用,因此您只需要两个“选择语句”。

【讨论】:

【参考方案2】:

我遇到了类似的问题,这就是我解决它的方法:

(当我解决这个问题时,我的动机是避免加入)

使用 2 个单独的集合:一个用于用户,一个用于 POSTS。将用户对象与帖子一起存储在帖子集合中。更改用户对象时不要更新帖子集合。维护用户信息的是USERS集合。当然,帖子数据最终会包含陈旧的用户信息,但用户多久更改一次他/她的个人资料。

如果您必须在每个帖子中显示绝对最新的用户信息,则从缓存中检索用户信息。

希望这对你有用。我的解决方案仍在开发中,所以我没有负载测试结果与您分享。

【讨论】:

以上是关于在 MongoDB 中模拟关系的主要内容,如果未能解决你的问题,请参考以下文章

MongoDb 模拟 2 个集合之间的连接

如何在 MongoDB 中建模关系? [复制]

Mongodb3.4.7搭建高可用集群

mongodb简介

mysql和mongodb的关系区别是啥

MongoDB关系与数据库引用