MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。他支持的数据结构很是松散,是相似json的bjson格式,所以能够存储比较复杂的数据类型。Mongo最大的特色是他支持的查询语言很是强大,其语法有点相似于面向对象的查询语言,几乎能够实现相似关系数据库单表查询的绝大部分功能,并且还支持对数据创建索引。
对于大多数的MongoDB的用户来讲,MongoDB就像是一个大黑盒。可是若是你可以了解到MongoDB一些内部构造的话,将有利于你更好地理解和使用MongoDB。
BSON
在MongoDB中,文档是对数据的抽象,它被使用在Client端和Server端的交互中。全部的Client端(各类语言的Driver)都会使用这种抽象,它的表现形式就是咱们常说的BSON(Binary JSON)。
BSON 是一个轻量级的二进制数据格式。MongoDB可以使用BSON,并将BSON做为数据的存储存放在磁盘中。
当Client端要将写入文档,使用查询等操做时,须要将文档编码为BSON格式,而后再发送给Server端。一样,Server端的返回结果也是编码为BSON格式再返回给Client端的。
使用BSON格式出于如下3种目的:
效率。BSON是为效率而设计的,它只须要使用不多的空间。即便在最坏的状况下,BSON格式也比JSON格式在最好的状况下存储效率高。
传输性。在某些状况下,BSON会牺牲额外的空间让数据的传输更加方便。好比,字符串的传输的前缀会标识字符串的长度,而不是在字符串的末尾打上结束的标记。这样的传输形式有利于MongoDB修改传输的数据。
性能。最后,BSON格式的编码和解码都是很是快速的。它使用了C风格的数据表现形式,这样在各类语言中均可以高效地使用。
写入协议
Client端访问Server端使用了轻量级的TCP/IP写入协议。这种协议在MongoDB Wiki中有详细介绍,它实际上是在BSON数据上面作了一层简单的包装。好比说,写入数据的命令中包含了1个20字节的消息头(由消息的长度和写入命令标识组成),须要写入的Collection名称和须要写入的数据。
数据文件
在MongoDB的数据文件夹中(默认路径是/data/db)由构成数据库的全部文件。每个数据库都包含一个.ns文件和一些数据文件,其中数据文件会随着数据量的增长而变多。因此若是有一个数据库名字叫作foo,那么构成foo这个数据库的文件就会由foo.ns,foo.0,foo.1,foo.2等等组成。
数据文件每新增一次,大小都会是上一个数据文件的2倍,每一个数据文件最大2G。这样的设计有利于防止数据量较小的数据库浪费过多的空间,同时又能保证数据量较大的数据库有相应的空间使用。
MongoDB会使用预分配方式来保证写入性能的稳定(这种方式可使用–noprealloc关闭)。预分配在后台进行,而且每一个预分配的文件都用0进行填充。这会让MongoDB始终保持额外的空间和空余的数据文件,从而避免了数据增加过快而带来的分配磁盘空间引发的阻塞。
名字空间和盘区
每个数据库都由多个名字空间组成,每个名字空间存储了相应类型的数据。数据库中的每个Collection都有各自对应的名字空间,索引文件一样也有名字空间。全部名字空间的元数据都存储在.ns文件中。
名字空间中的数据在磁盘中分为多个区间,这个叫作盘区。在下图中,foo这个数据库包含3个数据文件,第三个数据文件属于空的预分配文件。头两个数据文件被分为了相应的盘区对应不一样的名字空间。
上图显示了名字空间和盘区的相关特色。每个名字空间能够包含多个不一样的盘区,这些盘区并非连续的。与数据文件的增加相同,每个名字空间对应的盘区大小的也是随着分配的次数不断增加的。这样作的目的是为了平衡名字空间浪费的空间与保持某一个名字空间中数据的连续性。上图中还有一个须要注意的名字空间:$freelist,这个名字空间用于记录再也不使用的盘区(被删除的Collection或索引)。每当名字空间须要分配新的盘区的时候,都会先查看$freelist是否有大小合适的盘区可使用。
内存映射存储引擎
MongoDB目前支持的存储引擎为内存映射引擎。当MongoDB启动的时候,会将全部的数据文件映射到内存中,而后操做系统会托管全部的磁盘操做。这种存储引擎有如下几种特色:
MongoDB中关于内存管理的代码很是精简,毕竟相关的工做已经有操做系统进行托管。
MongoDB服务器使用的虚拟内存将很是巨大,并将超过整个数据文件的大小。不用担忧,操做系统会去处理这一切。要注意的是,MongoDB本身是无论理内存的,没法指定内存大小,彻底交给操做系统来管理,所以有时候是不可控的,在生产环境使用必须在OS层面监控内存使用状况。
MongoDB没法控制数据写入磁盘的顺序,这样将致使MongoDB没法实现writeahead日志的特性。因此,若是MongoDB但愿提供一种durability的特性,须要实现另一种存储引擎。
32位系统的MongoDB服务器每个Mongod实例只能使用2G的数据文件。这是因为地址指针只能支持32位。
特性
它的特色是高性能、易部署、易使用,存储数据很是方便。主要功能特性有:
面向集合存储,易存储对象类型的数据。
模式自由。
支持动态查询。
支持彻底索引,包含内部对象。
支持查询。
支持复制和故障恢复。
使用高效的二进制数据存储,包括大型对象(如视频等)。
自动处理碎片,以支持云计算层次的扩展性
支持RUBY,PYTHON,JAVA,C++,PHP等多种语言。
文件存储格式为BSON(一种JSON的扩展)
可经过网络访问
所谓“面向集合”(Collenction-Orented),意思是数据被分组存储在数据集中,被称为一个集合(Collenction)。每一个 集合在数据库中都有一个惟一的标识名,而且能够包含无限数目的文档。集合的概念相似关系型数据库(RDBMS)里的表(table),不一样的是它不须要定 义任何模式(schema)。
模式自由(schema-free),意味着对于存储在mongodb数据库中的文件,咱们不须要知道它的任何结构定义。若是须要的话,你彻底能够把不一样结构的文件存储在同一个数据库里。
存储在集合中的文档,被存储为键-值对的形式。键用于惟一标识一个文档,为字符串类型,而值则能够是各中复杂的文件类型。咱们称这种存储形式为BSON(Binary Serialized dOcument Format)。
其它
在《MongoDB The Definitive Guide》中介绍的MongoDB内部构造只有这么多,若是真要把它说清楚,可能须要另一本书来专门讲述了。好比内部的JS解析,查询的优化,索引的创建等等。有兴趣的朋友能够直接参考源代码:)mongodb