MongoDB 固定集合

在 MongoDB 中,固定集合(Capped Collection)是一种特殊类型的集合,它有一个固定的大小限制,一旦达到了这个大小限制,新的文档将会覆盖最早的文档。固定集合通常用于保存最新的数据,比如日志文件或者传感器数据。

固定集合特点

固定集合(Capped Collection)是 MongoDB 中的一种特殊类型的集合,它具有固定的大小限制。固定集合在某些场景下具有一些优点,但也存在一些限制和缺点。

集合优点

  • 高性能:固定集合的存储是预先分配的,不会产生碎片,因此读取和写入的性能通常比普通集合更高。

  • 顺序存储:固定集合的文档按照插入的顺序进行存储,可以方便地按照时间顺序查询和分析数据。

  • 自动覆盖旧数据:当固定集合达到大小限制时,新的文档会自动覆盖最早的文档,无需手动删除旧数据。

集合缺点和限制

  • 大小限制:固定集合的大小是固定的,一旦达到了大小限制,新的文档会覆盖最早的文档。这意味着固定集合不适用于需要永久保存所有数据的场景。

  • 无法删除指定文档:固定集合不支持 deleteMany() 和 deleteOne() 方法,只能使用 remove() 方法来删除文档。这意味着无法删除指定的文档,只能删除整个集合。

  • 无法更新文档大小:固定集合的文档可以被更新,但是更新的文档大小不能超过原始文档的大小。如果需要更新的文档大小超过了原始文档的大小,就需要先删除原始文档,再插入新的文档。

固定集合使用场景

由于固定集合存在高性能、顺序存储、自动覆盖旧数据的优点,那么固定集合在以下场景中可以发挥作用。

日志记录

固定集合非常适合用于存储日志数据。日志通常是按照时间顺序生成的,并且通常只需要保留最新的日志数据。使用固定集合可以确保日志数据的顺序存储,并且当达到大小限制时,新的日志数据会自动覆盖最早的日志数据。

传感器数据

固定集合也适用于存储传感器数据。传感器数据通常是实时生成的,并且只需要保留最新的数据。使用固定集合可以方便地按照时间顺序查询和分析传感器数据,并且当达到大小限制时,新的数据会自动覆盖最早的数据。

缓存数据

固定集合可以用于存储缓存数据。缓存数据通常是临时性的,只需要保留最新的数据。使用固定集合可以高效地存储和更新缓存数据,并且当达到大小限制时,新的数据会自动覆盖最早的数据。

创建固定集合

要创建一个固定集合,可以使用 createCollection() 方法,并指定 capped 参数为 true,以及 size 参数来设置集合的大小限制。语法如下:

> db.createCollection("logs", { capped: true, size: 1048576 })
{ "ok" : 1 }

上述示例中,我们创建了一个名为 logs 的固定集合,大小限制为 1MB。

还可以通过 max 属性限制文档最大个数,例如:

> db.createCollection("logs", { capped: true, size: 1048576, max:1000 })
{ "ok" : 1 }

怎样判断集合是否为固定集合?下面判断 logs 集合是否为固定集合:

> db.logs.isCapped()
true

如果需要将已存在的集合转换为固定集合可以使用以下命令:

> db.runCommand({ "convertToCapped":"logs", size: 1048576, max: 1000 })
{ "ok" : 1 }

以上代码将已存在的 logs 集合转换为固定集合。

固定集合查询

固定集合文档按照插入顺序储存的,默认情况下查询就是按照插入顺序返回的,例如:

# 插入数据到 logs 集合
> db.logs.insertOne({ message:"log1" });
{
       "acknowledged" : true,
       "insertedId" : ObjectId("6503e9adf470730f2bc38485")
}
> db.logs.insertOne({ message:"log2" });
{
       "acknowledged" : true,
       "insertedId" : ObjectId("6503e9b0f470730f2bc38486")
}
> db.logs.insertOne({ message:"log3" });
{
       "acknowledged" : true,
       "insertedId" : ObjectId("6503e9b3f470730f2bc38487")
}

# 查询固定集合
> db.logs.find()
{ "_id" : ObjectId("6503e9adf470730f2bc38485"), "message" : "log1" }
{ "_id" : ObjectId("6503e9b0f470730f2bc38486"), "message" : "log2" }
{ "_id" : ObjectId("6503e9b3f470730f2bc38487"), "message" : "log3" }

也可以使用 $natural 调整返回顺序。例如:

> db.logs.find().sort({$natural:-1})
{ "_id" : ObjectId("6503e9b3f470730f2bc38487"), "message" : "log3" }
{ "_id" : ObjectId("6503e9b0f470730f2bc38486"), "message" : "log2" }
{ "_id" : ObjectId("6503e9adf470730f2bc38485"), "message" : "log1" }

注意:在 32 位机子上一个 cappped collection(固定集合)的最大值约为 482.5M,64 位上只受系统文件大小的限制。

说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
公众号