当 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 复杂性,它应该给你足够的输入来做出决定。
在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 复杂性,它应该给你足够的输入来做出决定。