Capped Collection 固定集合
简单介绍
capped collections 是性能出色的有着固定大小的集合,以LRU(Least Recently Used最近最少使用)规则和插入顺序进行age-out(老化移出)处理,自动维护集合中对象的插入顺序,在创建时 要预先指定大小。如果空间用完了,新添加的对象将会取代集合中最旧的元素。
永远保持最新的数据。
功能特点:
可以插入及更新,但更新不能超出collection的大小,否则更新是白。不允许删除,但是可以调用drop()删除集合中的所有行,但是drop之后需要显示地重建集合。
在32位机器上一个capped collection的最大值约482.5M,64位上只受系统文件大小的限制。
属性及用法
属性1:对固定集合进行插入速度极快
属性2:按照插入顺序的查询输出速度极快
属性3:能够在插入最新数据时,淘汰最早的数据。
用法1:存储日志信息
用法2:缓存一些少量的文档
创建固定集合
创建固定集合不像普通集合,固定集合需要显式创建使用,即使用createCollection命令来创建。
显式创建集合
> show dbs admin (empty) dt1 0.078GB dt2 0.078GB dt3 0.078GB local 0.078GB > db test > db.createCollection("c4") { "ok" : 1 } > show collections c4 system.indexes > db.c4.drop() true > show dbs admin (empty) dt1 0.078GB dt2 0.078GB dt3 0.078GB local 0.078GB test 0.078GB >
显示创建固定集合
db.createCollection("my_collction",{capped:true,size:10000})
创建一个集合为“my_collction”的固定集合,大小为10000字节。还可以限定文档个数。加上Max:100属性。
注意:指定文档上限,必须指定大小。文档限制时在容量没满时进行淘汰,要是满了,就根据容量限定进行淘汰。
> use dt4 switched to db dt4 > db dt4 > show collections > > db.c1.insert({user:"happy",gender:"male"}) WriteResult({ "nInserted" : 1 }) > > show collections c1 system.indexes > db.c1.stats() { "ns" : "dt4.c1", "count" : 1, "size" : 112, "avgObjSize" : 112, "storageSize" : 8192, "numExtents" : 1, "nindexes" : 1, "lastExtentSize" : 8192, "paddingFactor" : 1, "systemFlags" : 1, "userFlags" : 1, "totalIndexSize" : 8176, "indexSizes" : { "_id_" : 8176 }, "ok" : 1 } > db.system.indexes.find() { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "dt4.c1" } >
现在创建一个固定集合c2。设置集合大小为10000000字节,大约10M;文档上限为5.
查看c2的状态发现,除了命名空间ns变了。storagesize、max、capped几个参数也值得注意。
> db.createCollection("c2",{capped:true,size:10000000,max:5}) { "ok" : 1 } > show tables c1 c2 system.indexes > db.c2.stats() { "ns" : "dt4.c2", "count" : 0, "size" : 0, "storageSize" : 10002432, "numExtents" : 1, "nindexes" : 1, "lastExtentSize" : 10002432, "paddingFactor" : 1, "systemFlags" : 1, "userFlags" : 0, "totalIndexSize" : 8176, "indexSizes" : { "_id_" : 8176 }, "capped" : true, "max" : 5, "ok" : 1 } >
那么,我们现在来向c2中插入文档数据,看看会发生什么。
> db.c2.insert({name:"user1"}) WriteResult({ "nInserted" : 1 }) > db.c2.insert({name:"user2"}) WriteResult({ "nInserted" : 1 }) > db.c2.insert({name:"user3"}) WriteResult({ "nInserted" : 1 }) > db.c2.insert({name:"user4"}) WriteResult({ "nInserted" : 1 }) > db.c2.insert({name:"user5"}) WriteResult({ "nInserted" : 1 }) > db.c2.find() { "_id" : ObjectId("55069b2ac1728741d70b54fa"), "name" : "user1" } { "_id" : ObjectId("55069b32c1728741d70b54fb"), "name" : "user2" } { "_id" : ObjectId("55069b38c1728741d70b54fc"), "name" : "user3" } { "_id" : ObjectId("55069b3dc1728741d70b54fd"), "name" : "user4" } { "_id" : ObjectId("55069b42c1728741d70b54fe"), "name" : "user5" } > db.c2.insert({name:"user6"}) WriteResult({ "nInserted" : 1 }) > db.c2.find() { "_id" : ObjectId("55069b32c1728741d70b54fb"), "name" : "user2" } { "_id" : ObjectId("55069b38c1728741d70b54fc"), "name" : "user3" } { "_id" : ObjectId("55069b3dc1728741d70b54fd"), "name" : "user4" } { "_id" : ObjectId("55069b42c1728741d70b54fe"), "name" : "user5" } { "_id" : ObjectId("55069b50c1728741d70b54ff"), "name" : "user6" } >
那么能不能把我们的普通集合转化为固定集合呢?答案是可以的。
转换集合
把普通的集合转换成固定集合
需要使用convertTocapped命令
db.runCommand({convertToCapped:"c1",size:10000})
把c1普通集合转换为固定集合,大小设置为10000字节。
自然排序
固定集合文档按照插入顺序存储,默认情况查询就是按照插入顺序返回的,也可以使用$natural调整返回顺序。
db.my_collections.find().sort({"$natrual":1})
1表示默认顺序,-1则相反。
这里做个小结,判断一个集合是否是固定集合有两种方法:
一种是 db.c2.isCapped()
另一种是db.c2.stats()
下面我们来实际操练一下如何将普通集合转换为固定集合。
> db.c1.isCapped() false > db.runCommand({convertToCapped:"c1",size:10000000,max:3}) { "ok" : 1 } > db.c1.isCapped() true > db.c1.stats() { "ns" : "dt4.c1", "count" : 1, "size" : 56, "avgObjSize" : 56, "storageSize" : 10002432, "numExtents" : 1, "nindexes" : 1, "lastExtentSize" : 10002432, "paddingFactor" : 1, "systemFlags" : 1, "userFlags" : 0, "totalIndexSize" : 8176, "indexSizes" : { "_id_" : 8176 }, "capped" : true, "max" : NumberLong("9223372036854775807"), "ok" : 1 } >