从另一个表中引用的表中获取数据的时间复杂度是多少


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_id列引用的user表中获取相应的user信息。

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

如果user集合中的那些附加列包含在image集合中,从而破坏规范化,那么速度性能会显著更好吗?

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

请注意,mongoose(在撰写本文时为v6(不使用$lookup,而是";称为populate((的更强大的替代方案";由于它是mongoose,所以大部分时间都花在客户端上,将bson分解为json,然后将json合并到mongoose模型中。

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

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

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

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

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

数据修改比时间复杂性更需要考虑。虽然去规范化可能会显著提高查询速度,但它打开了一个完整的数据同步蠕虫罐头——如果你改变";相应的用户信息";在用户表中,它不会自动反映在存储在";图像";收集

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

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

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

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

因此,这种方法有明显的性能开销(然而,在"现实生活"中,这种差异通常是疏忽的(,尽管如此,我个人仍然更喜欢";归一化";在大多数情况下。

这两种方法之间有一个折衷,如果你的用户从未更新,图像集合的额外存储使用量是没有问题的,那么也许你可以从打破";归一化";。这实际上取决于你的产品使用情况。

在实际决定这一点之前,需要考虑许多因素,在我看来,(数据的(规模和实际性能需要是的前两个因素

相关内容

  • 没有找到相关文章

最新更新