Not Only SQL

一、MongoDB概述

1.NoSQL简介

  1. 概念:NoSQL(Not Only SQL的缩写),指的是非关系型数据库,是对不同于传统的关系型数据库的数据库管理系统的统称。用于超大规模数据的存储,数据存储不需要固定的模式,无需多余操作就可以横向扩展。

  2. 特点

    • 优点:具有高可扩展性、分布式计算、低成本、架构灵活且是半结构化数据,没有复杂的关系等。
    • 缺点:没有标准化、有限的查询功能、最终一致是不直观的程序等。
  3. 分类

二、MongoDB简介

  1. 概念:MongoDB 是由C++语言编写的一个基于分布式文件存储的开源文档型数据库系统。

  2. 功能:JSON 文档模型、动态的数据模式、二级索引强大、查询功能、自动分片、水平扩展、自动复制、高可用、文本搜索、企业级安全、聚合框架MapReduce、大文件存储GridFS。

    • 面向集合文档的存储:适合存储Bson(json的扩展)形式的数据;
    • 格式自由,数据格式不固定,生产环境下修改结构都可以不影响程序运行;
    • 强大的查询语句,面向对象的查询语言,基本覆盖sql语言所有能力;
    • 完整的索引支持,支持查询计划;
    • 使用分片集群提升系统扩展性;
  3. 数据类型

三、概念详解

  1. 数据库:MongoDB 默认的数据库为”db”,该数据库存储在data目录中。单个实例可以容纳多个独立的数据库,每一个都有自己的集合和权限,不同的数据库也放置在不同的文件中。

  2. 集合:集合就是 MongoDB 文档组,类似于 RDBMS 的表格。集合存在于数据库中,集合没有固定的结构,这意味着你在对集合可以插入不同格式和类型的数据,但通常情况下我们插入集合的数据都会有一定的关联性。

  3. 文档:一个键值(key-value)对(即BSON)。MongoDB 的文档不需要设置相同的字段,并且相同的字段不需要相同的数据类型,这与关系型数据库有很大的区别,也是 MongoDB 非常突出的特点。

四、MongoDB CLI

4.1.增删改

4.2.操作符

4.3.查询

  1. 基本操作

  2. 聚合查询

  3. 管道操作:MongoDB的聚合管道将MongoDB文档在一个管道处理完毕后将结果传递给下一个管道处理

五、索引和高可用

5.1.索引

  1. 作用:索引通常能够极大的提高查询的效率,如果没有索引,MongoDB在读取数据时必须扫描集合中的每个文件并选取那些符合查询条件的记录。索引主要用于排序和检索。
    MongoDB使用 ensureIndex() 方法来创建索引,ensureIndex()方法基本语法格式如下所示:

    • db.collection.createIndex(keys, options)
      语法中 Key 值为要创建的索引字段,1为指定按升序创建索引,如果你想按降序来创建索引指定为-1,也可以指定为hashed(哈希索引)。
  2. 索引属性

    • background:是否后台构建索引,在生产环境中,如果数据量太大,构建索引可能会消耗很长时间,为了不影响业务,可以加上此参数,后台运行同时还会为其他读写操作让路,这个建议配置为true开启,这样来提高效率。
    • unique:是否为唯一索引
  3. 索引类型

    • 单键索引:
      在某一个特定的属性上建立索引,例如:db.users. createIndex({age:-1});
      1. mongoDB在ID上建立了唯一的单键索引,所以经常会使用id来进行查询;
      2. 在索引字段上进行精确匹配、排序以及范围查找都会使用此索引;
  • 复合索引:
    在多个特定的属性上建立索引,例如:db.users. createIndex({username:1,age:-1,country:1});

      1. 复合索引键的排序顺序,可以确定该索引是否可以支持排序操作;
      2. 在索引字段上进行精确匹配、排序以及范围查找都会使用此索引,但与索引的顺序有关;
      3. 为了性能考虑,应删除存在与第一个键相同的单键索引
    
  • 多键索引:
    在数组的属性上建立索引,例如:db.users. createIndex({favorites.city:1});

  • 哈希索引:
    不同于传统的B-树索引,哈希索引使用hash函数来创建索引。

      1. 在索引字段上进行精确匹配,但不支持范围查询,不支持多键hash;
      2. Hash索引上的入口是均匀分布的,在分片集合中非常有用;
    
  1. 优化目标
    • 根据需求建立索引
    • 每个查询都要使用索引以提高查询效率, winningPlan. stage 必须为IXSCAN ;
    • 追求totalDocsExamined = nReturned

5.2.高可用

  1. 可复制集
    可复制集是跨多个MongDB服务器(节点)分布和维护数据的方法。mongoDB可以把数据从一个节点复制到其他节点并在修改时进行同步,集群中的节点配置为自动同步数据;旧方法叫做主从复制,mongoDB 3.0以后推荐使用可复制集; 作用:
     1. 避免数据丢失,保障数据安全,提高系统安全性;
         (最少3节点,最大50节点)
     2. 自动化灾备机制,主节点宕机后通过选举产生新主机;提高系统健壮性;
         (7个选举节点上限)
     3. 读写分离,负载均衡,提高系统性能;
     4. 生产环境推荐的部署模式;
     
    
    原理:
     1. 数据同步:从节点与主节点保持长轮询;1.从节点查询本机oplog最新时间戳;2.查询主节点oplog晚于此时间戳的所有文档;3.加载这些文档,并根据log执行写操作;
     2. 阻塞复制:与writeconcern相关,不需要同步到从节点的策略(如: acknowledged Unacknowledged 、w1),数据同步都是异步的,其他情况都是同步;
     3. 心跳机制:成员之间会每2s 进行一次心跳检测(ping操作),发现故障后进行选举和故障转移;
     4. 选举制度:主节点故障后,其余节点根据优先级和bully算法选举出新的主节点,在选出主节点之前,集群服务是只读的;
     
    
    注意:
     MongoDB复制集里Primary节点是不固定的,所以生产环境千万不要直连Primary。
    
  1. 分片集群
    分片是把大型数据集进行分区成更小的可管理的片,这些数据片分散到不同的mongoDB节点,这些节点组成了分片集群。 作用:
     1. 数据海量增长,需要更大的读写吞吐量:存储分布式
     2. 单台服务器内存、cpu等资源是有瓶颈的:负载分布式
     
    
    注意:分片集群是个双刃剑,在提高系统可扩展性和性能的同时,增大了系统的复杂性,所以在实施之前请确定是必须的。 分片注意点:
     1. 热点 :某些分片键会导致所有的读或者写请求都操作在单个数据块或者分片上,导致单个分片服务器严重不堪重负。自增长的分片键容易导致写热点问题;
     2. 不可分割数据块:过于粗粒度的分片键可能导致许多文档使用相同的分片键,这意味着这些文档不能被分割为多个数据块,限制了mongoDB均匀分布数据的能力;
     3. 查询障碍:分片键与查询没有关联,造成糟糕的查询性能。 
     
    
    建议:
     1. 不要使用自增长的字段作为分片键,避免热点问题;
     2. 不能使用粗粒度的分片键,避免数据块无法分割;
     3. 不能使用完全随机的分片键值,造成查询性能低下;
     4. 使用与常用查询相关的字段作为分片键,而且包含唯一字段(如业务主键,id等);
     5. 索引对于分区同样重要,每个分片集合上要有同样的索引,分片键默认成为索引;分片集合只允许在id和分片键上创建唯一索引;
    

六、尾巴