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

1. MongoDB数据模型:

  • MongoDB数据存储结构:

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

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

    Double、String、Object、Array、Binary Data、Undefined、Object id、Boolean、Date、Null、Regular Expression、JavaScript、Symbol、JavaScript(with scope)、32-bit integer、Timestamp、64-bitInteger、Min key、Max key

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    {
    _id: "joe",
    name: "Joe Bookreader"
    } {
    patron_id: "joe",
    street: "123 Fake Street",
    city: "Faketon",
    state: "MA",
    zip: "12345"
    }

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

    {
    _id: "joe",
    name: "Joe Bookreader",
    addresses: [
    {
    street: "123 Fake Street",
    city: "Faketon",
    state: "MA",
    zip: "12345"
    }
    ]
    }

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

    符合我们一般设计原则,可是要获取完整数据的通信开销比較大,并且多个文档操作的原子性在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版本号支持的索引类型有例如以下几种:

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

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

  • 索引的属性:

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

构建方式如:

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

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

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

构建方式如:

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

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

构建方式如:

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

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

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

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

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

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

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

{ qty: 1 }
{ item: 1 }

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

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

另外索引的交集和包含:

索引的前缀交集:主要针对组合索引,查询计划会优化组合索引的前缀来查询。

  • 索引分析方法:

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

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

db.collection.totalIndexSize()
db.collection.stats()

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

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

db.collection.find().explain()

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

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

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

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

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. 应用市场快速下载以及网页端调起APP页面研究与实现

    Github博文地址,此处更新可能不是非常及时. 好久没写博客了,好大一个坑. 正好,近期刚做完应用市场的快速下载功能,便拿来填了这个坑. 话说产品为了添加用户量,提升用户活跃度以及配合推广,更坑爹的 ...

  2. 王立平--poser

    Poser是Metacreations公司推出的一款lemmaId=234814&ss_c=ssc.citiao.link" style="color:rgb(51,102 ...

  3. UESTC--1269--ZhangYu Speech(模拟)

    ZhangYu Speech Time Limit: 1000MS   Memory Limit: 65535KB   64bit IO Format: %lld & %llu Submit ...

  4. Regexp-Utils:银行卡号Luhm校验

    ylbtech-Regexp-Utils:银行卡号Luhm校验 1.返回顶部 1.方法 //Description: 银行卡号Luhm校验 //Luhm校验规则:16位银行卡号(19位通用): // ...

  5. [十二省联考2019] 异或粽子 解题报告 (可持久化Trie+堆)

    interlinkage: https://www.luogu.org/problemnew/show/P5283 description: solution: 显然有$O(n^2)$的做法,前缀和优 ...

  6. 1.Win32基本程序概念

    还没学会走之前,不要跑! Message based , event driven 每个程序都应该有一个如下的循环:MSG msg;while(GetMessage(&msg,NULL,NUL ...

  7. python初始面向对象

    阅读目录 楔子 面向过程vs面向对象 初识面向对象 类的相关知识 对象的相关知识 对象之间的交互 类命名空间与对象.实例的命名空间 类的组合用法 初识面向对象小结 面向对象的三大特性 继承 多态 封装 ...

  8. Tomcat 初探(二) server.xml 配置

    前言 在上一篇文章中,我们在示例中演示了网站的发布,其中涉及到了 server.xml 的修改,本文中我会给大家详细解释一下 server.xml 文件中的节点及其属性的作用,本片文章参考并摘抄了他人 ...

  9. Ubuntu14.04下Mongodb的Java API编程实例(手动项目或者maven项目)

    不多说,直接上干货! 若大家,不会安装的话,则请移步,随便挑选一种. Ubuntu14.04下Mongodb(在线安装方式|apt-get)安装部署步骤(图文详解)(博主推荐) Ubuntu14.04 ...

  10. 错误:java.lang.IllegalArgumentException: Receiver not registered

    Caused by: java.lang.IllegalArgumentException: Receiver not registered: com.multak.cookaraclient.Mai ...