写点什么

mongoDB

用户头像
刘帅强
关注
发布于: 1 小时前

MongoDB

介绍

  • 重新定义了 OLTP 数据库

  • 什么是 mongoDB?

  • 一个以 JSON 为数据模型的文档数据库

  • 为什么叫文档数据库?

  • 文档来自于“JSON Document”,并非我们一般理解的 PDF,WORD

  • 谁开发了 MongDB?

  • 上市公司 MongoDB Inc,总部位于美国纽约

  • 主要用途

  • 应用数据库,类似于 Oracle , MySQL,海量数据处理,数据平台

  • 主要特点

  • 建模为可选,JSON 数据模型比较适合开发者,横向扩展可以支撑很大数据量和并发

  • MongoDB 是免费的吗?

  • MongoDB 有两个版本:社区版和企业版,社区版基于 SSPL, 一种类似于 AGPL 基本类似的开源协议 企业版是基于商业协议,需要付费使用

  • MongoDB 优势

  • 简单直观: 以自然的方式来建模,以直观的方式来与数据库交互

  • 结构灵活:弹性模式从容响应需求的频繁变化

  • 多形性:同一个集合中可以包含不同西段(类型)的文档对象

  • 动态性:线上修改数据模式,修改是应用于数据库均无需下线

  • 数据治理:支持 JSON Schema 来规范数据模式。在保证模式灵活动态的前提下,提供数据治理能力

  • 快速开发: 做更多的事,写更少的代码

  • JSON 模型之快速特性:

  • 数据库引擎主需要一个存储区读写

  • 反范式,无关联的组织极大优化查询速度

  • 程序 API 自然,开发迅速

  • 原生的高可用和横向扩展能力

  • Replica Set -2 to 50 个成员

  • 自恢复

  • 多中心容灾

  • 滚动服务---最小化服务终端

  • 横向扩展

  • 需要的时候无缝扩展

  • 应用全透明

  • 多种数据分布策略

  • 轻松支持 TB -PB 数据级

安装 mongoDB

下载 MongoDB(server)


  • mongoDB.com/download-center

  • 企业版--开发环境免费用

  • 社区版--所有环境免费使用

  • 选择合适的 OS 版本

  • TGZ 版本包含 server mongodb tools 和 shell

  • cloud 版本

导入样本数据

  • curl -O -k https://raw.githubusercontent.com/tadpata/geektime-mongodb-couese/master/aggregation/dump.tar.gz

  • tar -xvf dump.tar.gz

  • mongorestore -h localhost:27017

mongodb Compass ui 界面操作的 monoDB

MongoDB 基本操作

  • 使用 insert 完成插入操作

  • 格式:

  • db.<集合>.insertOne(<JSON 对象>)

  • db.<集合>.insertMany (<JSON 1>,<JSON 2>,....<JSON n>)


  db.fruit.insertOne({name:"apple"})  db.fruit.insertMany([    {name:"apple"},    {name:"pear"},    {name:"orange"}  ])
复制代码


  • 使用 find 查询文档

  • 关于 find:

  • find 是 MongoDB 中查询数据的基本指令,相当于 SQL 中的 SELECT

  • find 返回的是游标

  • find 实例

  • db.movies.find({"year":1975}) //但条件查询

  • db.movies.find({"year":1989,"title":"Batman"}) //多条件 and 查询

  • db.movies.find({$and:[{"title":"Batman"},{"category":"action"}]}) // and 的另一种形式

  • db.movies.find({$or:[{"year":1989},{"title":"Batman"}]}) // 多条件 or 查询

  • db.movies.find({"title":/^B/}) //按正则表达式查找

  • 查询逻辑运算符

  • $lt: 存在并小于

  • $lte :存在并小于等于

  • $gt :存在并大于

  • $gte: 存在并大于等于

  • $ne: 不存在或存在但不等于

  • $nin:不存在或不在指定数组中

  • $or:匹配两个或多个条件中的一个

  • $and :匹配全部条件

  • 使用 find 查询子文档

  • field.sub_field

  • 控制 find 返回字段

  • 使用 remove 删除文档

  • remove 命令需要配合查询条件使用

  • 匹配查询条件的文档会被删除

  • 指定一个空文档条件会删除所有文档

  • 使用 Update 更新文档

  • update 操作执行格式:db.<集合>.update(<查询条件>,<更新字段>)

  • 使用 updateOne 表示无论条件匹配多少条记录,始终只显示第一条

  • 使用 updateMany 表示条件匹配多少条就更新多少条

  • updateOne/updateMany 方法要求更新条件部分必须具有以下之一,否则将报错

  • unset

  • pushAll/$pop

  • pullAll

  • $addToSet

  • 使用 update 更新数组

  • $push 增加一个对象到数组底部

  • $pushAll:增加多个独享到数组底部

  • $ pop 从数组底部删除一个对象

  • $pull :如果匹配指定值,从数组中删除相应的对象

  • $pullAll :如果匹配任意的值,从数组中删除相应的值

  • $addToSet: 如果不存在则增加一个值到数组

  • 使用 drop 删除集合

  • 使用 db.<集合>.drop()来删除一个集合

  • 集合中的全部文档都会被删除

  • 集合相关的索引也会被删除

  • 使用 dropDatabase 删除数据库

  • 使用 db.dropDatabase()来删除数据库

  • 数据库响应文件也会被删除,磁盘空间将被释放


    use tempDB     db.dropDatabase()    show collections()  //No  collections     shows dbs // The db is gone
复制代码

代码操作 mongoDB

  • python

  • 安装 Python MongoDB 驱动程序

  • pip install pymongo

  • 检查驱动程序

  • 在 python 交互模式下导入 pymongo, 检查驱动是否已正确安装 import pymongopymongo.version

  • 创建连接确定 MongoDB 连接串使用驱动连接到 MongoDB 集群,只需要指定 MongoDB 连接字符串即可,

  • mongodb ://数据库服务器主机地址:端口号初始化数据库连接


    from pymongo import MongoClient    uri = "mongodb://127.0.0.1:27017"    client = MongoClient(uri)    print client    
复制代码


  • 数据库操作: 插入用户


    db = client["eshop"]    user_coll = db["uesrs"]
复制代码


  • 插入一条新的用户数据


    new_user = {"username":"nina","password":"xxx","email":"123456@qq.com"}    reslt = user_coll.insert_one(new_user)    print result
复制代码


  • 更新用户需求变化,要求修改用户属性,增加字段 phone


  result = user_coll.update_one({"username":"nina"},{"$set":{"phone":"123456789"}})  print result
复制代码

聚合查询

  • 什么是 mongoDB 聚合框架

  • MongoDB 聚合框架(Aggreation Framework) 是一个计算框架,他可以

  • 作用在一个或或者几个集合上

  • 对集合中的数据进行一些列运算

  • 将这些数据转化为期望的形式

  • 从效果而言,聚合框架相当于 SQL 查询中的

  • GROUP BY

  • LEFT OUTER JOIN

  • AS

  • 管道(Pipeline) 和步骤(Stage)

  • 整个聚合运算过程称为管道(Pipline),它由多个步骤(Stage)组成,每个管道

  • 接受一系列文档(原始数据)

  • 每个步骤对这些文档进行一些列运算

  • 结果文档输出给下一个步骤


    pipline = [$stage1,$stage2,...$stageN]    db.<COLLECTION>.aggregrate(      pipline,      {options}    );
复制代码

复制集

复制集的作用

  • MongoDB 复制集的主要意义在于实现服务高可用

  • 它的实现依赖于两方面的功能:

  • 数据写入时将数据迅速复制到另一个独立节点上

  • 在接受写入的节点发生故障时自动选举出一个新的替代节点

  • 在实现高可用的同时,复制集实现了其他集合附加作用:

  • 数据分发:将数据赐给一个区域复制到另一个区域,减少另一个区域的读延迟

  • 读写分离: 不同类型的压力分别在不同节点上执行

  • 异地容灾:在数据中心故障时候快速切换到异地

典型复制集的结构

  • 一个典型的复制集有 3 个以上具有投票权的节点构成:

  • 一个主节点(PRIMARY): 接受写入操作和选举是投票

  • 两个(或多个)从节点(SECONDARY): 复制主节点上的新数据和选举时投票

  • 不推荐使用 Arbiter(投票节点)

数据是如何复制的?

  • 当一个修改操作,无论是插入,更新或删除,到达主节点时,它对数据的操作被记录下来(经过一些必要的转换),这些记录被称为 oplog

  • 从节点通过在主节点上打开一个 tailable 游标不断获取新进入主节点的 oplog,并在自己的数据上回放,以此保持跟主节点的数据一致

选举

  • 具有投票权的节点之间两两互相发送心跳

  • 当 5 次心跳未收到时判断为节点关联

  • 如果失联的是主节点,从节点会发起选举,选出新的主节点

  • 如果失联的是从节点则不会产生新的选举

  • 选举基于 RAFT 一致性算法实现,选举成功的必要条件是大多数投票节点存活

  • 复制集最多有 50 个节点,但是具有投票权的节点最多 7 个

影响选举的因素

  • 整个集群必须有大多数节点存活

  • 被选举为主节点的节点必须

  • 能够与多数节点建立连接

  • 具有较新的 oplog

  • 具有较高的优先级(如果有配置)

配置选项

  • 复制节点有以下常见的配置项

  • 是否具有投票权(v 参数): 有则参与投票

  • 优先级(priority 参数):优先级越高的节点越优先称为主节点。优先级为 0 的 节点无法成为主节点

  • 隐藏(hidden 参数):复制数据,但对应用不可见。隐藏节点可以具有投票权,但优先级必须是 0

  • 延迟(slaveDelay 参数):复制 n 秒之前的数据,保持与主节点的时间差

  • 关于硬件:

  • 因为正常的复制集节点都有可能成为主节点,它们的地位是一样的,因此硬件配置上必须一致。

  • 为了保证节点不会同时宕机,各节点使用的硬件必须具备独立性

  • 关于软件

  • 复制集节点软件版本必须一致,以避免出现不可预知的问题

  • 增加节点不会增加系统 写性能

试验

本次试验,我们通过在一台机器上运行 3 个实例来搭建一个简单的复制集,通过试验,我们将学会:

  • 如何启动一个 MongoDB 实例

  • 如何将 3 个 MongoDB 实例搭建成一个复制集

  • 准备

  • 安装最新版 MongoDB

  • Windows 系统需要事先设置好 MongoDB 可执行文件的环境变量

  • Linux 和 Mac 系统需要配置 PATH 变量

  • 确保有 10G 以上的硬盘空间

  • 创建数据目录 MongoDB 启动时将使用一个数据目录存放所有数据文件。 将为 3 个复制节点创建各自的数据目录。Linux /MacOS : mkdir 0p /data/db{1,2,3}windows :md c :\data\db1md c:\data\db2md c:\data\db3

  • 准备配置文件复制集的每个 MongoDB 进程应该位于不同的服务器。我们现在在一台机器上运行 3 个进程,因此要为它们各自配置:

  • 不同端口

  • 不同的数据目录

  • 不同日志文件


      systemLog:            destination: file

path:/data/db2/mongod.log #log path logAppend: true storage: dbPath:/data/db2 net: bindIp:0.0.0.0 port:28018 #port replication: replSetName: rs0 processManagement: fork:true
复制代码


mongod -f db1/mongod.conf


MongoDB /mongorestore


  • 类似于 MySQL 的 dump/restore

  • 可以完全全库 dump : 不加条件

  • 亦可以根据条件 dump 部分数据:- q 参数

  • Dump 的同时跟踪数据就更:--oplog

  • Restore 是反操作,把 mongodump 的输出导入到 mongodb


 mongodump -h 127.0.0.1:27017 -d test -c test mongorestore -h 127.0.0.1:27017 -d test -c test xxx.json
复制代码

文档模型设计

什么是数据模型?

数据模型是一组由符号,文本组成的集合,用以准确表达信息,达到有效交流,沟通的目的。Steve Hoberman 霍格曼,数据建模经典教程

数据模型设计的设计元素

  • 实体 Entity

  • 描述业务的主要数据集合

  • 谁,什么,何时,为何,如何

  • 属性 Attribute

  • 描述实体里面的单个信息

  • 关系 Relationship

  • 描述实体与实体之间的数据规则

  • 结构规则:1-N, N-1, N-N

  • 引用规则:电话号码不能单独存在

  • 数据第三范式原则: 数据在库里尽量不可能存在冗余

JSON 文档模型设计特点

  • MongoDB 文档模型设计的三个误区

  • 不需要模型设计

  • MongoDB 应该用一个超级大文档来组织所有数据

  • MongoDB 不支持关联或者事务

  • 关于 JSON 文档模型设计

  • 文档模型设计是处于物理模型设计阶段(PDM)

  • JSON 文档模型通过内嵌数组或引用字段来表示关系

  • 文档模型设计不遵从第三范式,允许冗余

  • 为什么说 MongoDB 是无模式?

  • 严格来说, MongoDB 同样需要概念/逻辑建模

  • 文档模型设计的物理结构可以和逻辑层类似

  • MongoDB 无模式由来:

  • 可以省略物理建模的具体过程

  • 文档模型的设计原则:性能和易用

  • 性能 Performance

  • 开发易用 Ease of Development 关系数据库 VS 文档模型

基础设计

业务需求及逻辑模型 ------>逻辑导向------> 基础建模------> 集合,字段,基础形状


  • 建立基础文档模型


  1. 根据概念模型或者业务需推导出逻辑模型---找到对象

  2. 列出实体之间的关系(及基数) ---明确关系一对一


  • 基本原则 一对一关系以内嵌为主作为子文档形式或者直接在顶级不涉及到数据冗余

  • 注意点: 内嵌后导致文档大小超过 16MB 一对 N

  • 基本原则: 一对多关系同样以内嵌为主,用数组来表示一对多, 不涉及到数据冗余

  • 注意点 内嵌后导致文档大小超过 16MB, 数组长度太大,数组长度不确定多对多

  • 基本原则 不需要映射表, 一般用内嵌数组来表示一对多,通过冗余来实现 N-N

  • 注意点 内前后导致文档大小超过 16MB, 数组长度太大, 数组长度不确定


  1. 套用逻辑设计原则来决定内嵌方式---进行建模

  2. 完成基础模型构建技术需求,读写比例,方式及数量-----> 技术导向----->工况细化----> 引用关联


  • 最频繁的数据查询模式 基于内嵌的文档模型

  • 最常用的查询参数 根据业务需求

  • 最频繁的数据读写模式 使用引用来避免性能瓶颈 使用冗余来优化访问性能

  • 读写操作的比例

  • 数据量太小


MongoDB 关联查询


什么时候该使用引用方式?内嵌文档太大,数 MB, 或者超过 16MB 内嵌文档或数组会频繁修改内嵌数组元素会持续增长并且没有封顶 MongoDB 引用设计缺陷


  • MongoDB 对使用引用的集合之间并无外键检查

  • MongoDB 使用聚合框架 $lookup 来模仿关联查询

  • $lookup 只支持 lefter outer join

  • $lookup 的关联目标(from) 不能是分片表经验和学习------->模式导向------> 套用设计模式-----> 最终模式套用设计模式

  • 文档模型:无范式 无思维定式 充分发挥想象力

  • 设计模式:实战过屡试不爽的设计技巧,快速应用 IOT 场景的分桶设计模式 可以把存储空间降低 10 倍 问题:物联网场景下的海量数据存储----飞机监控数据


问题: 大文档,很多字段,很多索引解决方案:列转行问题:模型灵活了,如何管理文档不同版本?解决方案: 增加一个版本字段: "schema_version" :"2.0"问题: 统计网页流量排行解决方案 :使用近似计算 Increment by 10(x)问题:业绩排名,游戏排名,商品统计等精确统计解决:用预聚合字段

事务

writeConcern?

  • 什么是 writeConcern

  • writeconcern 决定一个写操作落到多少个节点上才算成功。writeConcern 常见的取值

  • 0 : 发起写操作,不关心是否成功

  • 1~ 集群最大数据节点数:写操作需要被复制到指定节点才算成功

  • majority :写操作需要被复制到大多数节点上才算成功

  • 发起写操作的程序将阻塞到写操作到达指定的节点数为止

  • 默认行为

  • 3 节点复制集不做任何特别设定(默认值)

  • 数据仅仅写入主节点或写入了内存中就返回成功

  • 复制节点后续会复制这个数据写入

  • 当主节点写入后复制节点没来得及复制数写入时,主节点崩溃 可能发生数据丢失 w:"all"w: "majority"j:"true"journal 定义如何才算成功

  • true : 写操作落到 journal 文件才算成功

  • false : 写操作到达内存即算成功

  • writeConcern 的意义

  • 对于 5 个节点的复制集来说写操作落到多少个节点上才算是安全的?

  • 3,4,5, majority

用户头像

刘帅强

关注

还未添加个人签名 2019.05.14 加入

测试小白 短期计划为:构建 测试开发的全貌,而非死磕某个知识点。

评论

发布
暂无评论
mongoDB