【问题标题】:What is the time complexity of fetching data from a table that is referenced in another table?从另一个表中引用的表中获取数据的时间复杂度是多少?
【发布时间】:2022-01-21 18:40:55
【问题描述】:
const image_schema = () => {
  const common_fields = {
    user_id: {
      type: mongoose.Schema.Types.ObjectId,
      ref: "user",
      required: true,
    },
    file_name: {
      type: String,
      required: true,
    },
  };
  return new mongoose.Schema(common_fields, {
    collection: `image`,
    timestamps: true,
  });
};

以上是 image 集合的 mongoDB 架构。

每当我需要获取此表中的行子集时,我还需要从user 表中获取相应的user 信息,该表由user_id 列引用。

user 表中提取附加列的时间复杂度是多少?

如果user 集合中的这些额外列包含在image 集合中,那么速度性能会显着提高,从而破坏规范化吗?

【问题讨论】:

    标签: sql database mongodb nosql relational-database


    【解决方案1】:

    从技术上讲,在 mongodb 端的 查询 时间,嵌入文档的 O(1)O(n) 的引用文档相比,但是有也是数据 transfer 和 mongoose hydration - 这两种情况都是 O(n)。本质上它是相同的 O(n) ,但梯度稍差。请阅读下面的详细信息。

    请注意 mongoose(撰写本文时为 v6)不使用 $lookup 但 "more powerful alternative called populate()" 并且由于它是 mongoose,大部分时间都花在客户端上将 bson 解组为 json,然后将 json 水合为 Mongoose 模型.

    Mongoose 批量获取 refs,默认为 5000 个文档,因此如果您查询的图像少于 5000 个,则获取所有引用的用户将是一个多查询。尽管从技术上讲它是 O(n),但绝对值非常小——如果用户适合工作集,那么查询数据服务器端就是毫秒的问题。您可能会花费更多时间将数据从 mongo 传输到客户端。

    将 bson 转换为 json 需要更多时间。它是 O(n),在这种情况下,n 是字段数 x 对象数。这是 mongo nodejs 驱动程序的一部分,您在这里唯一可以改进的是仅投影必填字段。

    最昂贵的部分是将 json 转换为 Mongoose。复杂度仍然是 O(n),但它非常耗时,甚至有一个 lean 选项可以跳过这一步并返回纯 json 以获得更高的性能。所以使用:

    .populate({
      path: 'user_id',
      select: <only required user's info> ,
      options: { lean: true}
    })
    

    将使开销可以忽略不计。请记住,用户的字段将是只读的。

    数据修改比时间复杂度更重要。虽然非规范化可能会显着提高查询速度,但它会打开蠕虫的整个数据同步罐 - 如果您更改用户表中的“相应用户信息”,它将不会自动反映在存储在“图像”中的用户信息中收藏。

    因此,如果您对数据进行非规范化,则需要考虑的事项很少:

    • 您需要更改用户更新逻辑以更新所有相关集合中的信息
    • 您可能需要将其包装在多文档事务中以确保数据完整性
    • 您需要从应用程序外部监控更改,例如使用 mongosh 手动更改

    【讨论】:

      【解决方案2】:

      从用户表中获取额外列的时间复杂度是多少?

      嗯,对于每个图像,您需要执行额外的读取,无论您是使用 $lookup 还是在初始获取后的代码中获取它。

      因此,这种方法存在明显的性能开销(但在“现实生活”中,这种差异通常是可以忽略不计的),也就是说,在大多数情况下,我个人仍然更喜欢“规范化”方法。

      这两种方法之间存在权衡,如果您的用户从未更新,图像集合的额外存储使用量是没有问题的,那么您可能会从打破“规范化”中受益。这实际上取决于您的产品使用情况。

      在实际做出决定之前需要考虑许多因素,我认为(数据的)规模和实际性能需要是前 2 个因素

      【讨论】:

        猜你喜欢
        • 2019-06-23
        • 2018-11-23
        • 2021-09-09
        • 1970-01-01
        • 2020-04-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-12-03
        相关资源
        最近更新 更多