当 table 包含引用另一个 table 的 _id 的列时,是否需要包含引用的 table 的列?

When a table contains column that references the _id of another table, do you need to include the columns of the referenced table?

在MongoDB,

假设我有一个名为 Skills 的 table,它有一列引用 Users 的主键。

涉及从 Skills 获取数据的查询还需要获取有关 Users 的数据。

问题:

Users 中包含将要获取的数据的列应该包含在 Skills table 中,还是应该简单地从 Users 中查找它们table?

已编辑:

哪种方式会更快?如果有差异,可以忽略不计吗?

应在用户 table 中查找这些列。将它们复制到技能 table 将违反规范化规则。

回答您问题的最佳方法是 运行 对您的数据集进行性能测试并衡量差异。您需要考虑的第一件事是数据集的大小以及与数据交互的方式(读取、更新、插入、删除)。

一般来说,$lookup 的工作方式与 SQL 的 JOIN 类似,但对于大型数据集,应避免将其作为多集合操作 can affect your performance

鉴于您的用户和技能,这似乎是一种多对多的关系,但是您可以研究的方法很少。这完全取决于您的数据访问模式和您的应用程序查询数据的方式。

两个合集

您的数据已规范化,但您依赖 $lookup。如果您查询没有技能的用户或没有用户的技能,这可能是有益的。与其他方法相比,它还使数据更新更容易

拥有一系列技能的用户集合

这个似乎很有趣,因为它是一对多的关系,而不是一对多的关系。它允许您以最快的方式检索具有相应技能的用户(无需 $lookup,只需按 _id 查询)。它还允许您根据他们的技能查询所有用户(可以对技能进行索引并且可以应用所有数组查询)。如果你想更新技能的名称或任何其他属性,你需要 运行 更新影响多个文档的语句,因为你的数据是非规范化的,它可以被认为是一个缺点,但是你知道这种情况是否会经常发生。任何其他技能聚合也是可能的

一系列用户的技能集合

这种情况似乎是一对多而不是一对多。这意味着当您的系统增长时,您的文档会变得巨大(想象一下有多少用户将拥有驾驶执照技能等)。另一个缺点是在跨多个文档复制时很难检索用户数据。更新用户数据也是如此。

两个独立的集合:具有嵌入式数据子集的技能和用户

您还可以考虑拥有最少用户信息(仅需要在查询中检索的属性)以及第二个用户集合的技能,反之亦然。在这种情况下,您在两个集合之间复制数据,这使得任何更新都很麻烦,但从查询性能的角度来看,它可能是最佳的。

如您所见,数据建模总是有一些缺点。您需要了解您的数据访问模式才能做出正确的选择。至少有 4 种不同的可能性,我鼓励尝试所有这些可能性,衡量性能以及 query/update 复杂性,它应该给你足够的输入来做出决定。