1-MongoDB - 上限集合

about

MongoDB3.6.12

默认的,MongoDB创建的集合都能根据存储数据变化,来动态的调整集合大小。而这里再介绍一种特殊的集合——上限集合(Capped Collection),见名知意,这是一种有存储上限的集合,所以可以称之为固定集合、限制集合。

上限集合类似于定长的循环队列,数据顺序追加到集合的尾部,当集合空间达到上限时,它就会通过覆盖集合中最旧的文档。

根据上限集合的特点,它的应用场景也非常广泛,比如应用于日志存储、各种记录。

上限集合的优势:

  • 上限集合的数据将会被顺序写入到磁盘的固定空间内,所以,I/O速度非常快,如果不建立索引,性能更好,因为查询不需要索引即可按插入顺序返回文档。没有这些索引开销,上限集合可以支持更高的插入吞吐量。
  • 由于自动覆盖的特性,我们无需额外的操作来删除旧的文档。

上限集合的相关操作

创建上限集合

我们必须使用db.createCollection()方式显式创建上限集合,并且指定集合的最大大小(以字节为单位)。MongoDB会以最大大小为该上限集合预先分配存储空间,这其中也包含了少量的上限集合内部开销的空间。

// 通过 capped:true 声明集合为上限集合
// 通过 size 指定上限集合的最大存储空间
db.createCollection("s13", {"capped": true, "size":1000})

// 还可以通过 max 参数控制集合中文档的数量
db.createCollection("s14", {"capped": true, "size":1000, "max": 1000})

// 查看集合是否是上限集合
db.s14.isCapped()

// 将普通集合声明为上限集合
// "convertToCapped" 指定集合名称
// size 指定声明为上限集合的大小
db.runCommand({"convertToCapped": "s11", "size": 1000})

注意,如果size值小于等于4096,则MongoDB会自动的将集合的size设置为4096。如果是其它数值,MongoDB也会自动的调整size值为256的整数倍。

另外,size字段是必须指定的,当同时指定max参数时,无论哪个先到达上限,MongoDB都会删除旧的文档。

插入数据

// 批量插入数据
for(i=0;i<1100;i++){db.s14.insert({"num": i, "k": "v", "date": new Date()})}

查询上限集合

// 默认以插入顺序显式
db.s14.find()
// 取反的话,需要sort
db.s14.find().sort({"$natural": -1})

// 查询上限集合的信息
db.s14.stats()

更新

我们可以对上限集合中的文档进行更新,但更新不能导致文档的size增大或缩小,否则更新失败:

// 原数据如下
db.s14.find({"_id": ObjectId("60195ee171d01c974c353318")})
{ "_id" : ObjectId("60195ee171d01c974c353318"), "num" : 1083, "k" : "v", "date" : ISODate("2021-02-02T14:17:05.855Z") }

// 更细操作, 将 k 的值由 v 改为 a
db.s14.update(
    {"_id": ObjectId("60195ee171d01c974c353318")},
    {"$set": {"k": "a"}}
)

// 由于更新后的 k 值没有引起size的改变,所以更新成功
db.s14.find({"_id": ObjectId("60195ee171d01c974c353318")})
{ "_id" : ObjectId("60195ee171d01c974c353318"), "num" : 1083, "k" : "a", "date" : ISODate("2021-02-02T14:17:05.855Z") }

// 下面的更新将会失败,报错: "errmsg" : "Cannot change the size of a document in a capped collection: 58 != 59"
db.s14.update(
    {"_id": ObjectId("60195ee171d01c974c353318")},
    {"$set": {"k": "v1"}}
)

删除

我们无法删除上限集合中的文档,但可以通过drop来删除集合:

db.s14.drop()

上限集合的特点

  1. 不能在一个上限集合上创建TTL索引:
db.s14.createIndex({"logTTL": 1}, {"expireAfterSeconds": 30})
{
	"createdCollectionAutomatically" : false,
	"numIndexesBefore" : 1,
	"numIndexesAfter" : 2,
	"ok" : 1
}
  1. 不能手动删除上限集合中的文档:
db.s14.remove({"num": 1099})
WriteResult({
	"nRemoved" : 0,
	"writeError" : {
		"code" : 20,
		"errmsg" : "cannot remove from a capped collection: t1.s14"
	}
})
  1. 在32位系统中一个cappped collection的最大值约为482.5M,而64位系统中的capped collection最大值只受系统文件大小的限制。

that's all,see also:

mongodb 上限集合 | mongodb 上限集合 | MongoDB 固定集合(Capped Collections) | MongoDB固定集合(capped collection) | MongoDB固定集合(capped collection)的知识小结

posted @ 2021-02-03 15:27  听雨危楼  阅读(570)  评论(0编辑  收藏  举报