我们正在采用MongoDB提供新的解决方案,目前正在尝试根据我们的需求设计最有效的数据模型,并考虑数据项之间的关系。
我们必须在用户,项目和列表之间保持三方关系。用户可以拥有许多项目和许多列表。列表将包含一个用户和多个项目。一个项目可以属于许多用户和许多列表。后者尤其重要 - 一个项目可能属于潜在的大量列表:数千,当然可能数十或数十万。未来可能甚至是数百万。我们需要能够在两个方向上导航这些关系:例如,获取列表中的所有项目或项目所属的所有列表。我们还需要解决方案是通用的,以便我们可以在需要时添加更多类型的文档和关系。
所以似乎有两种可能的解决方案。第一种是数据库中的每个文档都有一个由一系列ID组成的“关系”集合。因此,列表文档将具有包含所有项的ID的项目的关系集合以及具有用户的单个ID的关系集合。在此模型中,当项目属于许多用户或许多列表时,这些数组将变得庞大。
第二个模型需要一种新类型的文档,一个“关系”文档,用于存储每个合作伙伴的ID和关系名称。这会整体存储更多数据,因此会影响磁盘空间。在NoSQL中,它看起来像是一种“不自然”的方法来解决这个问题。
性能方面,空间方面,架构方面,这更好,为什么?
干杯, 马特
答案 0 :(得分:7)
这取决于您的访问模式。
嵌入式id数组更适合阅读。通过一次快速阅读,您可以获得所有相关对象的ID,现在可以进行获取。但是如果您的更新率很高,那么您将遇到一些麻烦,因为mongodb必须反复复制相同(已经很大)的对象,因为它超出了磁盘边界。
但这种解决方案非常不适合写入。想象一下属于几百万个列表的项目。你决定删除它。现在,您必须遍历所有这些列表并从其引用数组中提取此项的ID。这很令人兴奋,不是吗?
将引用存储为单独的文档有利于写入。添加,编辑和删除新引用非常快。但是这个解决方案需要更多的磁盘空间,更重要的是需要宝贵的RAM。读取也不是那么快,特别是如果你有很多参考文献。
考虑到你的数字(“未来甚至可能是数百万”),我会选择这个解决方案。您总是可以使用一些硬件来加速查询。扩展写入传统上是最困难的部分,在此解决方案中,写入速度快且可分解。
答案 1 :(得分:1)
我同意塞尔吉奥关于数据访问模式的关键。
我还添加了另外一种可能的解决方案,即存储具有三个属性的第四种文档类型 - 对每个用户,列表和项目的引用。该集合可以编入索引,以便在所有3个字段上快速访问,在所有字段上唯一索引以防止重复,并允许快速插入和删除。
最终,您不会以这种方式存储更多数据,因为如果您需要从双方查找关系("此用户在哪些列表中有哪些项目?""用户在列表中有哪些项目?")无论如何都需要复制参考文献。
感觉有关系,但有时这是最好的解决方案。