MongoDB数据模型和索引学习总结

1. MongoDB数据模型:

  • MongoDB数据存储结构:

    MongoDB针对文档(大文件採用GridFS协议)採用BSON(binary json,採用二进制编码)数据格式来存储和交换数据。Bson吸收了JSON schema-less的特点,存储结构松散,不须要像RDB(关系数据)那样事先定义数据存储的元数据结构。另外添加了多种数据类型的支持和优化,使读写更加高效。

    (1) BSON 支持的数据类型:

    1. DoubleStringObjectArrayBinary DataUndefinedObject idBooleanDateNullRegular ExpressionJavaScriptSymbolJavaScriptwith scope)、32-bit integerTimestamp64-bitIntegerMin keyMax key

    (2) BSON 在表现形式例如以下:

    1. { "_id" : ObjectId("542c2b97bac0595474108b48"), "ts" : Timestamp(1412180887, 1),"name":"steven"}

    (3) BSON 是MongoDB中的通信协议和数据存储格式: 在MongoDB中client和服务端通信採用的是BSON的文档格式。比如查询一段数据。须要这样写:

    1. db.steven.find({"name":"steven"})

    更新一段数据须要这样写:

    1. db.steven.update({"name":"steven"},{$set:{"name":"jianying"}})

    删除一段数据须要这样写:

    1. db.steven.remove({"name":"steven"})

    总之MongoDB中针对文档的CRUD的RPC通信格式均支持採用了BSON的数据格式。而且其存储格式也採用了BSON的格式类似:

    1. { "_id" : ObjectId("542c2b97bac0595474108b48"), "ts" : Timestamp(1412180887, 1),"name":"steven"}

    (4) BSON数据格式的编码:

    BSON的String类型均採用UTF-8编码。当中KV结构中 K值 和 字符串类型的V值,均採用UTF-8格式编码。假设使用的是其它格式则须要转码。而且针对K 值能够採用除下面要求外的随意UTF-8字符:

    1. a.键不能含有\o(空字符)
    2. b.$和.有特殊的含义,仅仅有在特定环境下採用使用
    3. c.下面划线"_"开头的键是保留的(不是严格要求的)

    而其他值类型的编码则依照详细数据类型的内置协议编码。

    MongoDB在数据模型的组织方式上,支持文档的引用和嵌套。详细介绍例如以下。

  • 数据模型设计模式 - 引用 和 嵌套:

    以引用的方式存储数据是一种MongoDB组织数据存储结构的模式,即一个文档中存储了检索还有一个文档须要的必要信息,举比例如以下:

    1. {
    2. _id: "joe",
    3. name: "Joe Bookreader"
    4. }
    5. {
    6. patron_id: "joe",
    7. street: "123 Fake Street",
    8. city: "Faketon",
    9. state: "MA",
    10. zip: "12345"
    11. }

    上面的文档是用户joe的信息。而以下那个文档则记录了他的地址信息。要依据joe的name检索地址信息。则须要先检索第一个文档,然后再检索第二个文档。而设计成 嵌套模式则表现为:

    1. {
    2. _id: "joe",
    3. name: "Joe Bookreader",
    4. addresses: [
    5. {
    6. street: "123 Fake Street",
    7. city: "Faketon",
    8. state: "MA",
    9. zip: "12345"
    10. }
    11. ]
    12. }

    这两种设计模式的均有各自的优缺点,引用模式被觉得是规范化的模式。减小了数据存储的冗余,结构设计清爽简单。

    符合我们一般设计原则,可是要获取完整数据的通信开销比較大,并且多个文档操作的原子性在MongoDB层面无法保证。 而被觉得非规范化的嵌套设计模式。则具备相反的特性。其有点是降低了通讯的成本,并且原子性在单条文档得以保证,缺点就是数据存在冗余。选择哪种数据组织方式事实上是一种权衡(trade-off)。

  • 注意点:

    (1) MongoDB 文档的大小必须小于16M,超过这个大小的话,要考虑使用GirdFs。

    (2) 增加的文档大小超出原先分配给它的空间,MongoDB会把这个文档移动到磁盘的另外一个位置。

    迁移文档比原位更新更要耗时,也会因此导致磁盘碎片问题。

    (3) 在MongoDB里面,操作的原子性级别保证到 document级别。

    (4) Bson 字符串採用UTF-8编码。

2. MongoDB索引结构:

  • MongoDB支持索引的类型:

    MongoDB採用B树的结构来组织索引(有效的支持等值查询和范围查询)。支持针对文档中随意字段构建索引,不论是单值、数组、文本、嵌套结构的字段,均可构建索引。

    MongoDB 针对BSON存储格式是一种全索引的支持策略。

    面对多而强大的Mongo索引,索引的设计对性能的提升有比較大的影响。眼下最新MongoV3.0版本号支持的索引类型有例如以下几种:

    1. 索引类型 简述
    2. Default _id 默认ID索引:Mongo默认构建唯一性索引的id字段,每一个文档都有一个_id字段。
    3. Single Field 单值索引:针对文档的某一字段或或嵌套文档的某一字段构建索引。
    4. Compound Index 组合索引:将多个字段放在一起构建索引。字段索引间组成上下层的树形结构。
    5. Multikey Index 多值索引:针对数组类型的索引结构,为数组的每一个值建立一个索引。
    6. Geospatial Index 地理位置索引: 针对地理坐标结构,构建索引。能高效定位坐标范围,属额外福利。
    7. Text indexes 文本索引:类似搜索引擎的文本检索,涉及到分词操作,可惜不支持中文,并且查询语法的支持相对单一。
    8. Hashed Indexes 哈希索引:为了支持 基于HashSharding(一种部署方式)而生。仅仅支持等值检索,不支持范围检索。

    以上介绍了索引的类型,而不同类型的索引又能够带有下面属性,间接例如以下:

  • 索引的属性:

(1) 唯一索引: 和RDB(关系型数据库)的唯一性索引的概念一致。为了避免出现反复的值而设计。

构建方式如:

  1. db.members.createIndex( { "user_id": 1 }, { unique: true } )

(2) 稀疏索引: 稀疏索引的稀疏性体如今,其仅仅为那些包括索引字段的文档构建索引Entry。

忽略那些不包括索引字段的文档。

构建方式如:

  1. db.addresses.createIndex( { "xmpp_id": 1 }, { sparse: true } )

(3) TTL索引: TTL顾名思义是生命周期的意思。即存储的document存储带有过期时间属性,超过生命周期自己主动删除。像日志数据、系统自己主动产生的暂时数据、会话数据等均符合这一场景。

构建方式如:

  1. db.log_events.createIndex( { "createdAt": 1 }, { expireAfterSeconds: 3600 } )
  • 索引结构和特性:

(1) B树结构,顺序存储:MongoDB的索引均採用B树的结构组织,支持高效的等值查询和范围查询。

且内部索引项(entry)是默认有序的,能够天然保证返回结果有序。

(2) 索引的排序:构建索引是能够指定索引项是依照升序或降序构建。升序或降序的选择对于单值索引来说是等效的,可是对于组合索引则不等学效,组合索引被组织成上下级的树形结构,升序或降序选择错误。会对性能产生较大影响。

(3) 索引的交集:2.6版本号以后,索引的查询优化策略支持索引的交集,能够将多条索引组合来使用,最高效的检索数据。

比如能够构建两条单独的索引。当查询条件关联到这两条索引的时候。索引优化计划会自己主动组合这两条索引来检索。

比如构建了例如以下2条索引:

  1. { qty: 1 }
  2. { item: 1 }

则下面查询语句会命中以上两条索引:

  1. db.orders.find( { item: "abc123", qty: { $gt: 15 } } )

另外索引的交集和包含:

  1. 索引的前缀交集:主要针对组合索引,查询计划会优化组合索引的前缀来查询。
  • 索引分析方法:

(1) 评估RAM容量,尽量保证索引在内存中:

查询索引大小的命令(单位是字节):

  1. db.collection.totalIndexSize()
  2. db.collection.stats()

(2) 分析查看索引的计划:

MongoDB中使用explain和hint能够查看索引的策略:

  1. db.collection.find().explain()

能够看出那条索引策略生效,以及索引交集的使用情况。

  1. db.collection.find().hint({"name":1})

hint的命令则能够指定强制使用某条索引。

(3) 索引的管理信息: 每一个DB以下都会有一个system.indexes集合,这个集合记录着DB下,索引构建的元数据信息。

  1. db.system.indexes.find()
  • 注意点:

    (1) 每一个索引须要至少8K的空间。

    (2) MongoDB 会对 _id字段自己主动创建唯一索引。

    (3) 一个特别的索引类型支撑了TTL集合的实现,TTL依赖一个在Mongod中的后台线程。该线程读取索引中日期类型的值并从集合中删除过期的documents。

MongoDB数据模型和索引学习总结的更多相关文章

  1. MongoDB数据模型(二)

    原文地址 接上一篇 四.模型树结构 父引用的模型树结构 这个数据模型描述了一个树形结构,在子节点中存储父节点的引用. 模式 父引用模式存储每个树节点到文档中,除了树节点外,文档还存储了父节点的id. ...

  2. 深入理解MongoDB的复合索引

    更新时间:2018年03月26日 10:17:37   作者:Fundebug    我要评论 对于MongoDB的多键查询,创建复合索引可以有效提高性能.这篇文章主要给大家介绍了关于MongoDB复 ...

  3. SQL索引学习-聚集索引

    这篇接着我们的索引学习系列,这次主要来分享一些有关聚集索引的问题.上一篇SQL索引学习-索引结构主要是从一些基础概念上给大家分享了我的理解,没有实例,有朋友就提到了聚集索引的问题,这里列出来一下: 其 ...

  4. mongodb的地理位置索引

    mongoDB支持二维空间索引,使用空间索引,mongoDB支持一种特殊查询,如某地图网站上可以查找离你最近的咖啡厅,银行等信息.这个使用mongoDB的空间索引结合特殊的查询方法很容易实现.前提条件 ...

  5. MySQL中的联合索引学习教程

    MySQL中的联合索引学习教程 这篇文章主要介绍了MySQL中的联合索引学习教程,其中谈到了联合索引对排序的优化等知识点,需要的朋友可以参考下   联合索引又叫复合索引.对于复合索引:Mysql从左到 ...

  6. NodeJS,MongoDB,Vue,VSCode 集成学习

    NodeJS,MongoDB,Vue,VSCode 集成学习 开源项目地址:http://www.mangdot.com

  7. MongoDB小结23 - 索引简介

    MongoDB中的索引,可以看作是书的目录. 想象一下给你一本没有目录的书,然后让你去查询指定内容,我只想说,我不是电脑,我很蛋疼! 让你翻没有目录的书,就跟让电脑查询没有索引的集合一样,从头查询到尾 ...

  8. 第二课 MongoDB 数据模型

    1.课程大纲 本课程主要介绍MongoDB数据模型相关知识.包含文档.集合与数据库的基本概念.用法及命名规则:MongoDB主要的数据类型介绍以及MongoDB Shell的简单介绍与使用. 文档 ( ...

  9. MongoDB(八):索引

    1. 索引 索引支持查询的有效地提高效率.没有索引,MongoDB必须扫描集合的每个文档,以选择与查询语句匹配的文档.这种扫描效率很低,需要MongoDB处理大量的数据. 索引是特殊的数据结构,以易于 ...

随机推荐

  1. 例题2.8 总是整数 LA4119

    1.题目描写叙述:点击打开链接 2.解题思路:本题利用差分序列的性质解决.将1,2,..,k+1都带入表达式计算,假设对全部的i.都有D整除P(i),那么该序列全部值都为整数,否则不都为整数. 由于假 ...

  2. SharePoint 2013 开启訪问请求

    1.通常,我们进入SharePoint 2013网站,假设没权限会提示该网站未被共享,而没有切换账号或者申请訪问,实在是非常流氓:事实上,SharePoint为我们提供了訪问请求页面.可是可能须要手动 ...

  3. C++实现位数组

    当我们遇到大量整数排序时候为了节省内存空间我们能够考虑使用bit数组来实现,缺点是其仅仅适用于正整数. 思想: 在32位系统一个int类型占4个字节,按位来计算一个int类型能够记录32个数.因此,採 ...

  4. angularjs1-5,class,

    <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...

  5. Hello The World! —— 致我们无悔的IT之旅

    感谢IT,让我有了这么可爱活泼的伙伴. 有了KsCla,Coming,lhx_QAQ,tututu,AB_ever,Fat-zhang,wka,lhm这些伙伴神犇的陪伴,我的OI历程不至于那么枯燥无味 ...

  6. 用select拼接insert into,单引号转义

    SELECT 'INSERT INTO dbo.CMS_Transformation ( TransformationName , TransformationCode , Transformatio ...

  7. 升级Xcode8后的相机crash问题-IOS10权限问题

    当我升级到Xcode8后,启动我的相机项目,直接crash,输出的日志如下: '2016-07-08 16:41:11.268943 project-name[362:56625] [MC] Syst ...

  8. Java-SpringCloud:Spring Cloud 是什么

    ylbtech-Java-SpringCloud:Spring Cloud 是什么 1.返回顶部 1. 一.概念定义       Spring Cloud是一个微服务框架,相比Dubbo等RPC框架, ...

  9. JavaScript学习笔记——对象的创建

    对象是JavaScript基本数据类型,在JavaScript中除了Undefined.Null.布尔型(ture.false).字符串和数字之外,其他的都属于对象. 在JavaScript中,一个对 ...

  10. 10.QT程序框架与connect

    MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setup ...