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()
上限集合的特点
- 不能在一个上限集合上创建TTL索引:
db.s14.createIndex({"logTTL": 1}, {"expireAfterSeconds": 30})
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}
- 不能手动删除上限集合中的文档:
db.s14.remove({"num": 1099})
WriteResult({
"nRemoved" : 0,
"writeError" : {
"code" : 20,
"errmsg" : "cannot remove from a capped collection: t1.s14"
}
})
- 在32位系统中一个cappped collection的最大值约为482.5M,而64位系统中的capped collection最大值只受系统文件大小的限制。
that's all,see also:
mongodb 上限集合 | mongodb 上限集合 | MongoDB 固定集合(Capped Collections) | MongoDB固定集合(capped collection) | MongoDB固定集合(capped collection)的知识小结