一、什么是MongoDB?

MongoDB是由C++等语言开发的面向文档的数据库管理系统(文档是半结构化数据的一种,允许相同类的实体可以拥有不同的属性)。MongoDB使用类JSON格式BSON存储数据。



{
    title:"MongoDB",
    last_editor:"192.168.1.122",
    last_modified:new Date("27/06/2011"),
    body:"MongoDB introduction",
    categories:["Database","NoSQL","BSON"],
    revieved:false
}



上述示例是一个简单的BSON结构体,由多个键值对元素组成。

MongoDB属于NoSQL,在数据模型的概念上与关系型数据库有所区别。




MongoDB设置查询超时 mongodb时间段查询_mongodb时间范围查询


可以发现:MongoDB没有JOIN这一操作,取而代之的是使用嵌入文档或引用的形式。


{
  _id: <ObjectId1>,
  name: "draveness",
  books: [
    {
      _id: <ObjectId2>,
      name: "MongoDB: The Definitive Guide"
    },
    {
      _id: <ObjectId3>,
      name: "High Performance MySQL"
    }
  ]
}


上述示例中的books即为嵌入的子文档,作为对象存储在父文档中。


MongoDB设置查询超时 mongodb时间段查询_键值对_02


引用则是MongoDB中的标准化数据模型,文档间可以通过主键(_id)来进行链接。

二、MongoDB架构

MongoDB的架构和MySQL类似,默认的WiredTiger存储引擎所使用的默认数据结构也是B树,但WiredTiger所使用的B树与MySQL有所不同,且该引擎还支持使用LSM树结构。


MongoDB设置查询超时 mongodb时间段查询_mongodb时间范围查询_03


三、WiredTiger存储结构

WiredTiger使用B树结构存储数据,但实际上是一种更类似B+树的结构。


MongoDB设置查询超时 mongodb时间段查询_查询优化_04


如上是一个简化的结构图,内存中的B树分为三种节点,而磁盘中的数据则是紧凑的以Extent为单位排列。


MongoDB设置查询超时 mongodb时间段查询_键值对_05


在内存中,树的每个节点是一个页,根节点和内节点分别包含指向子页的页索引指针,叶节点包含键值对数据(WT_ROW array)和指向父页的指针,每条记录保留自己在页上的偏移量。

在磁盘上,每个页包含一个页头和块头以及真正的键值对数据,其中页头定义了页的类型、页中实际载荷数据的大小、页中记录条数等;块头定义页的checksum、块的磁盘寻址地址等。

WiredTiger通过一个块设备管理模块为页分配块,定位某一键值对数据时,先通过块的位置找到页,再通过页找到数据的偏移位置。

四、MongoDB查询优化

查询优化器是MongoDB的一部分,如果存在可用的索引,它会为给定查询选择一个最高效的索引。在为查询选择理性的索引时,优化查询器使用了一套相对简单的规则:

  • 避免scanAndOrder,如果查询中包含排序,尝试使用索引进行排序。
  • 通过有效的索引约束来满足所有字段--尝试对查询选择器里的字段使用索引。
  • 如果查询包含范围查找或者排序,那么对于选择的索引,其中最后用到的键需能满足该范围查找或者排序。

如果某个索引能满足以上所有这些条件,那么它会被视为最佳索引并予以使用。要是有多个最佳索引,则任意选择一个。可以遵循这条经验:如果能为查询构建最优索引,查询优化器的工作能更轻松些。

参考文章

『浅入浅出』MongoDB 和 WiredTiger - 面向信仰编程draveness.me

MongoDB设置查询超时 mongodb时间段查询_数据_06

Mongodb WiredTiger存储结构www.jianshu.com

MongoDB设置查询超时 mongodb时间段查询_数据_07

WiredTiger存储引擎之一:基础数据结构分析mongoing.com MongoDB实战-MongoDB的查询优化器与hint()_wanght89的专栏-CSDN博客blog.csdn.net

MongoDB设置查询超时 mongodb时间段查询_数据_08