MongoDB中海量关系的最佳数据模型

Posted

技术标签:

【中文标题】MongoDB中海量关系的最佳数据模型【英文标题】:Best data model for massive relationships in MongoDB 【发布时间】:2012-02-24 09:13:15 【问题描述】:

我们正在将 MongoDB 用于新的解决方案,目前正在尝试设计最有效的数据模型以满足我们的需求,即数据项之间的关系。

我们必须在用户、项目和列表之间保持三向关系。一个用户可以有许多项目和许多列表。一个列表将有一个用户和许多项目。一个项目可以属于许多用户和许多列表。后者尤其重要——一个项目可能属于大量的列表:数千,当然也可能是数万或数十万。未来甚至可能达到数百万。我们需要能够在两个方向上导航这些关系:例如,获取列表中的所有项目或项目所属的所有列表。我们还需要通用的解决方案,以便我们可以在需要时添加更多类型的文档以及它们之间的关系。

所以似乎有两种可能的解决方案。第一个是数据库中的每个文档都有一个由 ID 数组组成的“关系”集合。因此,列表文档将有一个包含所有项目 ID 的项目的关系集合和一个具有用户单个 ID 的关系集合。在这个模型中,当一个项目属于很多很多用户或很多很多列表时,这些数组将变得非常庞大。

第二种模型需要一种新型文档,即存储每个合作伙伴的 ID 和关系名称的“关系”文档。这将存储更多数据,因此会影响磁盘空间。在 NoSQL 中解决这个问题的方法看起来也很“不自然”。

性能方面、空间方面、架构方面,哪个更好?为什么?

干杯, 马特

【问题讨论】:

【参考方案1】:

这取决于您的访问模式。

嵌入的 id 数组更适合阅读。通过快速阅读,您可以获得所有相关对象的 ID,现在可以去获取它们。但是如果你的更新率很高,你就会遇到一些麻烦,因为 mongodb 将不得不一遍又一遍地复制相同的(已经很大的)对象,因为它超出了它的磁盘边界。

但是这个解决方案真的不利于写入。想象一个属于几百万个列表的项目。你决定删除它。现在您必须遍历所有这些列表并从它们的参考数组中提取该项目的 id。这很令人兴奋,不是吗?

将引用存储为单独的文档有利于写入。添加、编辑和删除新引用非常快。但是这个解决方案需要更多的磁盘空间,更重要的是,需要宝贵的 RAM。读取速度也没有那么快,尤其是在您有很多参考文献的情况下。

鉴于您的数字(“未来可能甚至数百万”),我会采用此解决方案。您总是可以投入一些硬件来加速查询。传统上,扩展写入是最难的部分,在此解决方案中写入速度快且可分片。

【讨论】:

感谢您的全面回答。我将尝试使用数组,因为读取速度比写入速度重要得多,并且更新问题可以在代码中解决(我们不需要更新关系,因此可以绕过它们)。【参考方案2】:

我同意 Sergio 关于数据访问模式是关键的观点。

我还添加了另一种可能的解决方案,即存储具有三个属性的第四种文档类型——对用户、列表和项目中的每一个的引用。该集合可以被索引以快速访问所有 3 个字段,对所有字段进行唯一索引以防止重复,并允许快速插入和删除。

最终您不会以这种方式存储更多数据,因为如果您需要从双方查找关系(“此用户在哪些列表中拥有哪些项目?”和“哪些用户在他们的列表中有此项目? ") 无论如何你都需要复制引用。

感觉是相关的,但有时这是最好的解决方案。

【讨论】:

“感觉是有关系的” - 有关系并没有错 :-) 我认为我们不能走这条路,因为我们必须对新的数据类型和关系持开放态度,这将我们开始使用的三个硬连接到模型中。不过感谢您的建议。 我不知道为什么这比任何其他方法的限制或多或少 - 你能再举一个例子吗?

以上是关于MongoDB中海量关系的最佳数据模型的主要内容,如果未能解决你的问题,请参考以下文章

MongoDB中的多对多关系

哪个是 MongoDB 数据库模型的最佳设计?

海量数据模型实施方法论恢复

mongodb bsondump 有啥作用

如何处理mongodb中的多对多关系

Mongodb数据模型