当前位置: 首页 > 知识库问答 >
问题:

与MongoDB的大规模多对多关系

严景焕
2023-03-14

MongoDB多对多关联

如何在MongoDB中组织多对多关系

我在这种设置中看到的问题是MongoDB的16MB文档限制。假设我有users、groups和posts。帖子有一个关联的和许多可能喜欢它的用户中有许多post和许多user可以跟随它。一个用户可以有许多喜欢的帖子并且可以跟随许多。如果我要用一个关系数据库来构建它,我会这样设置它:

user:
    user_id
    username

post:
    post_id
    group_id
    message

group:
    group_id
    name

post_likes:
    post_id
    liked_user_id

group_followers:
    group_id
    follower_user_id

理论上,如果在SQL查询中正确分页,则可以有有限数量的帖子和跟随的用户帖子可以有无限数量的喜欢的用户用户可以有无限数量的喜欢的帖子和他们跟随的

我如何设置MongoDB的模式以实现这种规模?

共有1个答案

岳嘉石
2023-03-14

这是一个很好的问题,它说明了过度铺垫的问题和如何处理。

让我们继续用用户喜欢帖子的例子,这是一个简单的例子。其他关系也要相应处理。

你是绝对正确的,与存储喜欢在帖子迟早会导致问题,非常流行的帖子将达到大小限制。

因此您正确地返回到创建post_likes集合。为什么我说这是正确的?因为它适合您的用例以及功能性和非功能性需求!

  • 它的尺度是不确定的(嗯,理论上有一个极限,但它是巨大的)
  • 它易于维护(在post_idliked_user_id上创建唯一的索引)和使用(用户和post都是已知的,因此添加like是简单的insert或更可能是upsert)
  • 您可以轻松找到哪些用户喜欢哪篇文章,哪些用户喜欢哪篇文章

但是,我将稍微扩展集合,以防止对某些频繁的用例进行不必要的查询。

现在让我们假设帖子标题和用户名不能更改。在这种情况下,以下数据模型可能更有意义

{
  _id: new ObjectId(),
  "post_id": someValue,
  "post_title": "Cool thing",
  "liked_user_id": someUserId,
  "user_name": "JoeCool"
}

现在让我们假设您想要显示喜欢一篇文章的所有用户的用户名。对于上面的模型,这将是一个单一的、相当快速的查询:

db.post_likes.find(
  {"postId":someValue},
  {_id:0,user_name:1}
)

如果只存储ID,那么这个相当普通的任务将需要至少两个查询,并且--考虑到可能有无限数量的Liker用于后续的约束--潜在的巨大内存消耗(您需要将用户ID存储在RAM中)。

现在问题来了:即使用户名和帖子标题会发生变化,您也只需进行多次更新:

db.post_likes.update(
  {"post_id":someId},
  { $set:{ "post_title":newTitle} },
  { multi: true}
)

您认为,需要一段时间来做一些非常罕见的事情,比如更改用户名或帖子,以获得极快的用例速度,这是非常经常发生的。

记住MongoDB是一个面向文档的数据库。因此,用将来查询所需的值记录您感兴趣的事件,并相应地为数据建模。

 类似资料:
  • 问题内容: 我想创建一个与用户类对象之间的多对多关系。 我有这样的事情: 问题是我是否可以在内部使用类引用。还是我必须使用欧洲工商管理学院的?还是有另一种(更好的)方法呢? 问题答案:

  • 是否可以与用户建立多对多关系?我试图制作一个简单的实体 但是当我从列表中选择用户并选择Save时,它给出了错误 org.springframework.dao.InvalidDataAccessApiUsageExc的:org.hibernate.瞬态对象异常:对象引用未保存的瞬态实例-保存瞬态实例前冲洗:com.mycompany.myapp.domain.用户;嵌套异常java.lang.Il

  • 问题内容: 代表具有属性的多对多关系的最“ mongo”方式是什么? 因此,例如: MYSQL表 => => => 解决方案1 将人们嵌入电影中…? 在MongoDB中,我知道这样做很好,但是我不想让人们看电影,从逻辑上讲这没有任何意义。因为人们不一定只属于电影。 解决方案2 并且将两个单独的集合。 =>嵌入 =>嵌入 该解决方案的问题在于,当我们要为特定对象更新人员时,我们需要运行两个更新查询以

  • 问题内容: 我正在尝试使用Ohm在Redis中创建多对多关系。例如,我有如下定义的Book和Author模型: 我想做的是利用Ohm的索引功能来进行以下发现: 使用上面的代码,我得到以下异常:Ohm :: Model :: IndexNotFound:找不到索引:author_id。(尝试查找提供给作者的图书时) 我已尝试按照此处所述构建自定义索引:http : //ohm.keyvalue.or

  • 我对MongoDB中的多对多关系实现有一个特定的问题。 我收集了歌曲和艺术家的作品(数百万份文档)。在这里,这首歌可以被许多艺术家演唱,一个艺术家可以唱许多首歌。所以我在两个集合中都遵循了文档引用的方法。像这样... 1.歌曲集:- 2.艺术家收藏:- 但这里的问题是,在删除艺术家的同时,我必须从歌曲所有文档中的艺术家数组中删除一个艺术家,如果该文档中有艺术家,反之亦然。这会导致原子性问题。我如何

  • 我还想知道如何定义每个模型上的关系--你是否需要或者是否可以只在用户上定义关系?