分享

mongodb指南(十) - developer zone - 集合

 HiLinz 2014-07-18

mongodb指南(十) - developer zone - 集合

分类: mongodb翻译 582人阅读 评论(0) 收藏 举报

mongodb集合实质上就是一组文档的名称。你可以认为它们大体上等同于关系型数据库中的表。

概述

一个mongodb集合是一个BSON格式文档的集合。这些文档通常有着相同的结构,但是这并不是必须的,因为mongodb是模式自由(或者更准确的说,“动态模式”)的数据库。你可以在同一个集合内存储多种多样的文档,而且你不需要预先定义集合的“列”或者字段。

 

一个集合在第一个文档插入时创建。

 

集合名称应当以字母或者下划线开始并且可以包含字母;$是保留字符。集合可以使用命名空间进行划分;这些集合组的命名使用“.”(点)来定义。例如,你可以定义集合blog.posts和blog.authors,都属于"blog"的命名空间。注意这只是个方便用户管理的机制--从数据库的角度看,集合命名空间是平面的。

集合名称最多可以包含128字符(包括数据库和索引的名称)。最好将它控制在80/90个字符。

shell

以编程方式,我们使用"."标记访问这些集合。例如,使用mongo shell:

  1. if( db.blog.posts.findOne() )  
  2. print("blog.posts exists and is not empty.");  

其他访问集合的方法有:

  1. > db["mycol"].find()  
  2. > db.getCollection("mycol").find()  

尽管下划线允许使用,但是在shell中如果第一个字符是下划线则表示一个特殊函数:shell认为这个提示符是实际的javascript值,而不是一个集合名称。所以此时使用"."标示是不能访问的,但是可以使用getCollection()来访问。

  1. > db._mycol.find() --> error  
  2. > db.getCollection("_mycol").find() --> success  

定容量集合

定容量集合是固定大小的集合,它们拥有高性能自动-FIFO过期特征(过期是基于插入顺序的)。它们有点类似于“RRD”的概念。

另外,定容量集合可以高性能的自动维护对象在集合中的插入顺序;这在有些场合中的效率非常好,比如日志功能。

定容量集合是不能被分片的。

创建

不同于标准的集合,你必须显式的创建一个定容量集合,指定集合大小,单位是字节。该集合的数据空间就会预分配好。提醒一下指定的大小包含了数据库的头信息。

  1. > db.createCollection("mycoll", {capped:true, size:100000})  

特性

  • 一旦空间用完,新添加的对象会覆盖集合中的老对象。
  • 如果你执行find()并且不指定排序,返回的对象永远是按照插入顺序来排序。反向排序可以使用find().sort({$natural:-1})来得到。

使用和约束

  • 在定容量集合中,你可以添加新的对象。
  • 你可以更新集合中已经存在的对象。但是,这些对象不能再增大空间了。如果这样做了,更新会失败。注意如果你在执行更新,你可以声明一个合适的索引(默认情况下定容量集合没有"_id"字段的索引)。
  • 数据库不允许从定容量集合中删除对象。使用drop()函数删除集合中所有的行。(drop之后你必须显式的重建这个集合)
  • 定容量集合不能被分片。

应用

  • 日志.定容量集合为存储日志文档到数据库提供了高性能的方法。插入对象到没有索引的定容量集合和日志到一个文件系统的性能非常接近。另外,借助于内建的FIFO机制,在日志应用中你没有超出磁盘空间的风险。
  • 缓冲。如果你希望在数据库中缓冲小数量的对象,或许缓冲一些计算信息,定容量集合提供了很方便的机制来实现它。注意在这种应用中你需要在定容量集合上使用索引,因为这种应用的读频率高于写。
  • 自动存档。如果你希望数据自动过期,定容量集合要比手写cron scripts更加方便。

建议

  • 如果可以,不要在定容量集合上面建立索引。如果该集合的写频率远大于读频率,那最好没有索引。注意你可以在一个定容量集合上面建立索引;但是,此时你会从“日志速度”插入变成了“数据库速度”插入--这就是说,相比于数据库标准它的速度依然很快。
  • 使用natural ordering来更有效的获取最新插入的对象。这和在日志文件尾部追加数据(tail on a log file)有些类似。

可选项

大小

定容量集合的大小是必须指定的。

最大

你还可以固定集合中的对象个数。一旦这个限制达到了,最先插入的对象会被移出。

注意:当指定对象个数时,你必须指定集合大小。一定要留有足够的空间存储限制的对象数,否则对象移出速度会超乎你的想象。你可以使用validate()工具查看定容量集合使用的空间大小,并且从这里估计你需要的大小。

  1. db.createCollection("mycoll", {capped:true, size:100000, max:100});  
  2. db.mycoll.validate();  

autoIndexId

autoIndexId字段可以设为true或者false来显示的使能或者禁止在_id字段自动创建唯一索引。

如果你会用到_id字段,你就应当在_id字段创建一个索引。

鉴于有些时候并不会使用_id索引,不使用_id字段对插入会很有帮助。大部分驱动和mongo shell在客户端增加_id。查看各驱动文档如何取消这一功能(不同驱动表现可能不同)。在mongo shell你可以这样做:

  1. > db.mycollection._mongo.insert(db.mycollection._fullName, myObjectWithoutAnId)  

检查一个集合是否是定容量的

你可以使用shell中的函数isCapped()来检查一个集合是否为定容量的。db.foo.isCapped()

将一个集合转换为定容量的

你可以使用convertToCapped命令将一个(非定容量)集合转换为定容量集合:

  1. > db.runCommand({"convertToCapped": "mycoll", size: 100000});  
  2. { "ok": 1 }  

createCollection命令

使用createCollection命令来显示的创建一个集合。它通常被用来创建定容量集合。

  1. > # mongo shell  
  2. > db.createCollection("mycoll", {capped:true, size:100000})  
  3. > show collections  

大多数驱动还有一个创建集合的助手函数。你可以通过它运行任何命令。

  1. > db.runCommand( {createCollection:"mycoll", capped:true, size:100000} )  

renameCollection命令

这个命令用来对已存在的集合重命名。

shell:

  1. > db.oldname.renameCollection("newname")  

在驱动中,你可以使用通用的命令语法来创建:

  1. > db.runCommand( { renameCollection: "mydb.oldname", to: "mydb.newname" }  

这个命令是原子执行的,在生产版本DB上面运行应当是安全的。它改变了和这个集合相关的元数据并从旧的命名空间拷贝索引元数据到新的命名空间。执行这个命令所花时间是恒定的,并且和集合或者索引的大小无关。如果重命名时在这个集合上面已经有一个打开的游标,那么这个游标会变得无效并且不能获取任何数据。

 

使用大数量的集合

在使用mongodb的很多场合,有一个小技巧是使用多个集合存储信息代替使用单个集合.通过这种方式,一些重复数据不再需要存储在每个对象中,建立它上面的索引就可以删除了。更重要的是为了性能(基于这个问题),数据可以被指定的组操作进行聚集。

例如,假定我们记录对象/文档到数据库,并需要有M条记录:可能一条dev记录,一条debug记录,一个ops记录等等。我们可以把他们都存储在同一个集合“logs”中,类似于:

  1. { log : 'dev', ts : ..., info : ... }  

不过,如果记录条数并不是很多的话,每种log使用一个集合会比较好一些。我们可以使用一个"logs.dev"集合,一个“logs.debug”集合,“logs.ops”,等:

  1. // logs.dev:  
  2. { ts : ..., info : ... }  

当然,这也只有在我们不需要同时查询多种类型log的情况下才有意义。

通常情况下,使用大量集合没有显著的性能缺陷,相反会带来很好的性能表现。

限制

默认情况下,mongodb中对每个数据库可以使用的集合限定在24000个命名空间.每个命名空间是628字节,.ns文件默认是16MB。

每一个集合被记为一个命名空间,每一个索引也同样记为一个命名空间。这样如果每个集合有一个索引,我们可以创建最多12000个集合。参数--nssize允许你增大这个限制。

提醒一下每个集合有一个最小空间开销--一些KB。更进一步,任何索引会需要至少8KB数据空间,因为b-tree也大小是8KB。如果这里有大量的集合,那么由于元数据会paged out,一些操作会变慢。

--nssize

如果需要更多集合,指定--nssize来运行mongodb。这会让<database>.ns文件变大并支持更多集合。注意--nssize仅影响新建的.ns文件 -- 如果你已经有个数据库并想调整大小,在使用--nssize运行数据库后,在从shell中运行db.repairDatabase()来调整大小。

.ns文件最大为2GB。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多