前面已经说过mongodb是文档型存储的,bson方式存储的,下面主要通过逻辑和物理两方面分别描述下mongodb的存储方式。

1、逻辑存储结构

先看一条数据:

save语句太长了,截图不好截,摘出来了:

db.user.save({name:"test_a",age:30,sex:"male",addr:{zcode:100000,waddr:
"北京市海淀区中关村",haddr:"北京市海淀区中关村",mobile:"13488888888", telep:"010-88888888"},job:
"高级工程师",hobby:["游泳","上网","爬山","骑行"]})


mongodb存储文件并返回前端 mongodb存储文章_mongodb

从图片可以看出,info是数据库名,user是传统表名(mongodb中叫collection)。再看这条信息,_id是自动生成的(我没有主动插入),addr是一个子文档,hobby是一个数组。由此可知mongodb的逻辑存储结构是:


mongodb存储文件并返回前端 mongodb存储文章_mongodb存储文件并返回前端_02


2、物理存储结构

directoryperdb=true,可以看到在定义的数据文件目录 /opt/mongodb/data/s1下面已经有一个info的文件夹,拿就是我在上面插入数据时创建的数据库(mongodb的数据库不需要额外的创建语句)。


mongodb存储文件并返回前端 mongodb存储文章_mongodb存储文件并返回前端_03

然后进入info目录,


mongodb存储文件并返回前端 mongodb存储文章_数据文件_04

数据文件在内部分为很多块,每一块保存一个名字空间的数据,块与块之间用链表连接,每块中的每条数据间也用链表连接。还有一个是16m的文件info.ns,info.ns是一个命名空间文件,用来保存名字空间对应的元数据,info.ns是一个hashtable,保存了每个名字空间中的储存信息,包括大小,块数,第一块位置,最后一块位置,索引信息等,而块的位置又通过文件序号(后面跟的数字)与文件中的偏移量来确定。

需要注意的是,我现在数据库里面只有一条不到2k的数据,为什么会有2个数据文件,一个64m,一个128m呢?

这正是由mongodb的存储空间预先分配决定的,当你开始往64m的文件中存储数据时,同时mongodb会预先分配一个128m的文件空间,并且用0来填充,这样每次都有一个文件的空间是完全没有存放数据的,虽然浪费了一定大小的空间,但是也免去了每次写入时分配空间消耗的时间,加快了存储速度。

看一下我在网上找的一张图片,mongodb的文件内部存储结构:


mongodb存储文件并返回前端 mongodb存储文章_数据库_05