【问题标题】:MongoDB - Many-to-many relationship?MongoDB - 多对多关系?
【发布时间】:2018-01-18 23:37:33
【问题描述】:

我很好奇如何构建具有多对多关系且可能包含数万条记录的 MongoDB。

假设您有一个餐厅数据库,该数据库跟踪大量餐厅以及所有入住这些餐厅的人。因此,用户可能想要查找一个人并查看他们已登记入住的所有餐厅,但也可以查找一家餐厅并查看所有已登记入住的人。

如何以一种有意义且易于搜索和更新的方式来构建它?

【问题讨论】:

    标签: mongodb


    【解决方案1】:

    您给出的示例与大多数真实世界的多对多关系示例一样,实际上是 few-to-few 关系的示例。您可能有许多餐厅和许多食客,但与整个集合相比,任何给定的餐厅只为一小部分食客提供服务,而大多数个人食客只会光顾一小部分餐厅。这听起来像是一个稀疏链接的网络,其中链接密度比明显低于 1。

    为了测量网络的链接密度(边缘密度),我们计算 现有链接 m 与可能链接总数的比率。 对于 N 个节点的网络,网络链路密度为 D = m / 0.5*N*(N-1) 全连接网络的(最大)链路密度D为1。 - Network-Science

    但是,您问的是多对多,那么我们以神经网络为例如何?神经网络通常形成密集网络,因此代表了真正的多对多网络。在这种情况下,答案很简单——不要使用 mongoDB。使用根据您的特定要求量身定制的自定义结构和序列化策略。毕竟,真正的多对多关系几乎总是异常值,因此需要进行特殊处理。

    话虽如此,在 mongoDB 中建模更常见的 few-to-few 关系可以在不牺牲丰富的文档结构的情况下实现,而实现这一点的方式取决于您的访问模式。

    因此,以餐厅/餐厅网络示例为例,如果您通常要查询餐厅的用餐者,那么您将创建一个包含每个餐厅的 diner_id 数组。另一种方式意味着每个用餐者都持有一组 restaurant_ids。两者都用于双向查询能力。

    必须小心,因为 mongoDB 中没有 foreign_key 约束,因此维护数据的引用完整性是您的责任。

    如果性能对您来说最重要,那么您可能希望将数据嵌入到每个文档中,而不是使用 id 来引用它。这是读取(而不是写入)的更高性能选项,因为所有数据都可以一次从磁盘中提取出来。这意味着当您更新数据值以确保数据的完整性时,您将需要做更多的工作,但这通常并不像最初看起来那样可怕。食客多久真正改变一次他们的名字?并且根据文档大小,您可能不一定要嵌入完整文档,数据的子集加上指向完整记录的 id 通常可以解决问题。

    简而言之,mongoDB 架构设计应该由应用程序需求驱动。不同应用程序的不同模式,而不是一个单一的关系数据库来统治它们。数据的真实情况如何?应用程序如何实际使用这些数据?存储的文档对象有多大?回答这些问题,您的架构实际上会自行设计。

    【讨论】:

    • “与整个集合相比,任何给定的餐厅只为一小部分食客提供服务,而大多数个人食客只会访问一小部分餐厅”我不知道。也许后者可能是真的,但是一家餐厅(经过几年的时间)可以拥有数以万计的独特食客。为了这个问题,我们假设每个人都去过数千家餐馆。
    • “为了这个问题,让我们假设每个人都去过数千家餐馆”——完全正确。为了使它成为一个真正的多对多示例,您需要使其不切实际,这是我的观点的一部分。事实是 MongoDB 并不特别支持多对多,因此处理它的方法是使用关系数据库中熟悉的通常的 3rd-normal-form,除非这对于像 mongoDB 这样的文档数据库效率低下。这通常会让 sql-boosters 欣喜若狂,但现实世界中的多对多实际上非常罕见。
    • “大脑神经元确实形成了一个密集的网络”——我认为这是错误的。如果我没记错的话,D 是人脑的 2E-7。 1E+11 个节点,每个节点 1E+4 个链接。 human-memory.net/brain_neurons.html
    • @Jona - 你是对的。我说:...how about we use a neural network as the example;这是正确的,但后来我继续将它从小型、密集的人工神经网络交换到以brain 为代表的巨大、稀疏的自然网络。我现在就去纠正它。谢谢。
    【解决方案2】:

    我会创建一个checkinsvisits 集合。当用户访问该餐厅时,会创建一个引用用户和餐厅的新文档。这是相当干净和简单的

    【讨论】:

      猜你喜欢
      • 2013-01-02
      • 2018-11-03
      • 2014-01-21
      • 2014-08-15
      • 2020-12-05
      • 1970-01-01
      • 2014-10-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多