【问题标题】:MongoDB Data Model - One document can link to multiple documents with different statusMongoDB 数据模型 - 一个文档可以链接到具有不同状态的多个文档
【发布时间】:2021-01-15 17:08:34
【问题描述】:

我目前正在处理一个问题,即 mongodb 的数据结构。我有两个集合:服务和用户。每个用户的服务将处于不同的状态,管理员可以为每个用户更改服务的状态。

服务集合:

[

    {

         _id: ObjectID(...),
         name: ...,
         status: [
             {
                 userId: ObjectID(...),
                 status: 0
             },
             {
                 userId: ObjectID(...),
                 status: 1
             },
             {
                 userId: ObjectID(...),
                 status: 4
             }
         ]
    }
]

用户集合:

[

    {
         _id: ObjectID(...),
         name: ...,
         email: ...,
         phone: ....
    }
]

这种结构适用于少量数据。但是,让我们想象一下,我们有 10,000 个用户和 1000 个服务,每个服务必须包含所有用户及其状态。我相信这不是很好。因此,我正在寻找一些简洁而好的解决方案。感谢您的阅读。

【问题讨论】:

  • 重要的是您对数据执行的操作类型,而不是数据量——这应该是决定数据模型的因素。那么,请告诉您将对这些数据执行哪些重要操作(查询和更新)?您还可以尝试将服务嵌入到用户集合中(而不是将用户嵌入到服务中)。
  • 感谢您的回复。我的功能主要集中在服务上,所以我决定将用户嵌入到服务中。所以,即使我有 10,000 个用户,他们的状态嵌入在服务集合中,一切都应该是好的,对吧?
  • 嵌入数组很好,只要这些数组的大小是已知的/有限的/恒定的并且不增长。 MongoDB 有许多方法和索引来处理数组。
  • 如果用户数量增加,它就不会很好地扩展。 MongoDB 对文档大小有一个限制,即 16MB,因此当服务的用户数量超过此限制时,您将不得不处理它。同样在这种情况下,任何时候您需要获取服务文档,您都将获取所有用户,这将增加流量。或者,您每次查询服务时都需要使用聚合管道和预测。
  • @prasad_ 问题是规模会随着时间的推移而增长,因为会有更多用户注册。

标签: mongodb database-design data-modeling


【解决方案1】:

似乎必须对用户有一个服务状态的概念,可以将其存储在专用集合中。它将有一个用户 ID、一个服务 ID 和一个状态。在这种情况下,状态可以独立于用户或服务进行管理,并且解决方案将更具可扩展性。集合看起来像:

[
  {
    _id: ObjectId(...),
    userId: ObjectId(...),
    serviceId: ObjectId(...)
    status: 1
  }
]

如果您在查询服务时需要更多数据,您可以考虑将这些数据嵌入到服务状态对象内的用户或服务对象中(基本上是反规范化和冗余),但需要一些努力来保留这些数据与其他集合同步:

[
  {
    _id: ObjectId(...),
    user: {
      _id: ObjectId(...),
      name: ...
    },
    service: {
      _id: ObjectId(...),
      name: ...
    }
    status: 1
  }
]

其中userservice 字段是对用户和服务集合中数据的“引用”,它们是数据的“真实来源”。

【讨论】:

  • 您好,感谢您的建议。它看起来类似于关系 SQL 中的多对多概念。正如你之前提到的,一个文档的限制大约是 16MB,那么如果中间人集合超过了这个限制呢?
  • 是的,这基本上就是这个概念:用户和服务之间的多对多关系。 16MB 的限制是每个文档,而不是每个集合。基本上,集合可以增长到存储允许的大小,如果这还不够,它可以跨多个副本集进行分片,MongoDB 开箱即用地支持这一点。因此,这种方法没有 16MB 的限制。
  • 哦,文档限制不是收集限制。我的错。看起来多对多永远不会过时。感谢您提供有用的知识。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-20
  • 2017-02-14
  • 2014-02-25
  • 2020-11-19
  • 1970-01-01
相关资源
最近更新 更多