IT评测·应用市场-qidao123.com

标题: MongoDB学习笔记 [打印本页]

作者: 耶耶耶耶耶    时间: 2024-7-19 22:18
标题: MongoDB学习笔记
MongoDB

一.先容

1.1 NoSQL 和MongoDB

NoSQL=Not Only SQL,⽀持类似SQL的功能, 与Relational Database相辅相成。其性能较⾼,不使⽤SQL意味着没有布局化的存储要求(SQL为布局化的查询语句),没有约束之后架构更加灵活。
NoSQL数据库四⼤家族 列存储 Hbase,键值(Key-Value)存储 Redis,图像存储 Neo4j,⽂档存储 MongoDB
MongoDB 是⼀个基于分布式⽂件存储的数据库,由 C++ 编写,可以为 WEB 应⽤提供可扩展、⾼性能、易摆设的数据存储办理⽅案。
MongoDB 是⼀个介于关系数据库和⾮关系数据库之间的产品,是⾮关系数据库中功能最丰富、最像关系数据库的。在⾼负载的环境下,通过添加更多的节点,可以保证服务器性能。
1.2 MongoDB 体系布局


RDBMSMongoDBdatabase(数据库)database(数据库)table (表)collection( 集合)row( ⾏)document( BSON ⽂档)column (列)field (字段)index(唯⼀索引、主键索引)index (⽀持地理位置索引、全⽂索引 、哈希索引)join (主外键关联)embedded Document (嵌套⽂档)primary key(指定1⾄N个列做主键)primary key (指定_id field做为主键) 1.3 BSON

BSON是⼀种类json的⼀种⼆进制形式的存储格式,简称Binary JSON,它和JSON⼀样,⽀持内嵌的⽂档对象和数组对象,但是BSON有JSON没有的⼀些数据范例,如Date和Binary Data范例。BSON可以做为⽹络数据互换的⼀种存储形式,是⼀种schema-less的存储形式,它的优点是灵活性⾼,但它的缺点是空间利⽤率不是很理想。
{key:value,key2:value2} 这是⼀个BSON的例⼦,此中key是字符串范例,后⾯的value值,它的范例⼀般是字符串,double,Array,ISODate等范例。
BSON有三个特点:轻量性、可遍历性、⾼效性
MongoDB使⽤了BSON这种布局来存储数据和⽹络数据互换。Document就是BSON格式
⼀个Document对应关系数据库就是⼀条记载(Record)
MongoDB中Document 中可以出现的数据范例
数据范例说明表明举例String字符串UTF-8 编码的字符串才是合法的{key:“cba”}Integer整型数值根据你所采⽤的服务器,可分为32位或64位{key:1}Boolean布尔值⽤于存储布尔值{key:true}Double双精度浮点值⽤于存储浮点值{key:3.14}ObjectId对象ID⽤于创建⽂档的ID{_id:new ObjectId()}Array数组⽤于将数组或列表或多个值存储为⼀个键{arr:[“a”,“b”]}Timestamp时间戳从开始纪元开始的毫秒数{ ts: new Timestamp() }Object内嵌⽂档⽂档可以作为⽂档中某个key的value{o:{foo:“bar”}}Null空值表示空值或者未定义的对象{key:null}Date或者ISODate格林尼治时间⽇期时间,⽤Unix⽇期格式来存储当前⽇期或时间{birth:new Date()}Code代码可以包含JS代码{x:function(){}}File⽂件1、⼆进制转码(Base64)后存储 (<16M)
2.GridFS(>16M)GridFS ⽤两个集合来存储⼀个⽂件:fs.files与fs.chunks 真正存储必要使⽤mongofiles -d gridfs put song.mp3 1.4 适⽤场景

适用场景:

具体应⽤场景:

应⽤特征:

1.5 搭建

去官网下载社区版,本文用的MongoDB 4.2.24,机器是mac,然后将压缩包解压即可
1.5.1 单机


1.5.2 复制集


复制集成员的配置参数
参数字段范例说明取值说明_id整数_id:0复制集中的标示,不能重复host字符串host:“主机:端⼝”节点主机名arbiterOnly布尔值arbiterOnly:true是否为仲裁(裁判)节点priority整数priority=0|1权重,默认1,是否有资格变成主节点,取值范围0-1000,0永远不会变成主节点hidden布尔值hidden=true|false,0|1是否潜伏,权重必须为0,才可以设置votes整数votes= 0|1是否为投票节点,0 不投票,1投票slaveDelay整数slaveDelay=3600从库的延迟多少秒buildIndexes布尔值buildIndexes=true|false,0|1主库的索引,从库也创建,_id索引⽆效 1.5.3 分片集群


二.命令

2.1 基本操纵

  1. 查看数据库:show dbs;
  2. 切换数据库 如果没有对应的数据库则创建:use 数据库名;
  3. 创建集合:db.createCollection("集合名")
  4. 查看集合:show tables;或show collections;
  5. 删除集合:db.集合名.drop();
  6. 删除当前数据库:db.dropDatabase()
复制代码
2.2 CURD

2.2.1 插入

单条:db.集合名.insertOne(BSON)
  1. db.testdb.insertOne({name:"张晓峰",birthday:new ISODate("2000-07-01"),gender:1,expectSalary:15000,city:"bj"})
复制代码
多条:db.集合名.insertMany([BSON,BSON])
  1. db.testdb.insertMany(
  2.     [{name:"李丽",birthday:new Date("1996-05-01 14:20:09"),gender:0,expectSalary:21000,city:"sz"},
  3.      {name:"李平",birthday:new Date("1997-07-01 14:20:09"),gender:0,expectSalary:22000,city:"sz"}])
复制代码
2.2.2 查询

db.集合名.find(条件)
比力查询
操纵条件格式例⼦RDBMS中的条件等于{key:value}db.col.find({字段名:值}).pretty()where 字段名=值大于{key:{$gt:value}}db.col.find({字段名:{$gt:值}}).pretty()where 字段名>值大于等于{key:{$gte:value}}db.col.find({字段名:{$gte:值}}).pretty()where 字段名>=值小于{key:{$lt:value}}db.col.find({字段名:{$lt:值}}).pretty()where 字段名<值小于等于{key:{$lte:value}}db.col.find({字段名:{$lte:值}}).pretty()where 字段名<=值不等于{key:{$ne:value}}db.col.find({字段名:{$ne:值}}).pretty()where 字段名!=值 逻辑条件查询
  1. and 条件:MongoDB 的 find() ⽅法可以传⼊多个键(key),每个键(key)以逗号隔开,即常规 SQL 的 AND 条件 db.集合名.find({key1:value1, key2:value2}).pretty()
  2. or 条件:db.集合名.find({$or:[{key1:value1}, {key2:value2}]}).pretty()
  3. not 条件:db.集合名.find({key:{$not:{$操作符:value}}).pretty()
复制代码
分⻚查询
db.集合名.find({条件}).sort({排序字段:排序⽅式})).skip(跳过的⾏数).limit(⼀⻚体现多少数据)
2.2.3 修改

  1. db.集合名.update(<query>,<update>,{upsert: <boolean>,multi: <boolean>,writeConcern: <document>})
复制代码
参数说明:

对于单实例应答的环境,是将数据写入到内存后开始应答,除非j:true,则保证掉电后不会丢失数据
2.2.4 删除

  1. db.collection.remove(<query>,{justOne: <boolean>,writeConcern: <document>})
复制代码
参数说明:

2.3 聚合操纵

聚合是MongoDB的⾼级查询语⾔,它允许我们通过转化归并由多个⽂档的数据来⽣成新的在单个⽂档⾥不存在的⽂档信息。⼀般都是将记载按条件分组之后进⾏⼀系列求最⼤值,最⼩值,均匀值的简单操纵,也可以对记载进⾏复杂数据统计,数据挖掘的操纵。聚合操纵的输⼊是集中的⽂档,输出可以是⼀个⽂档也可以是多个⽂档。
分类

2.3.1 单⽬的聚合操纵

单⽬的聚合命令常⽤的有:count() 和 distinct()
  1. db.lg_resume_preview.find({}).count()
复制代码
2.3.2 聚合管道(Aggregation Pipeline)

MongoDB中聚合(aggregate)主要⽤于统计数据(诸如统计均匀值,求和等),并返回盘算后的数据结果。
表达式:处理输⼊⽂档并输出。表达式只能⽤于盘算当前聚合管道的⽂档,不能处理别的的⽂档。
表达式描述$sum盘算某个字段的总和或者求count$avg盘算均匀值$min获取集合中所有⽂档对应值得最⼩值$max获取集合中所有⽂档对应值得最⼤值$push在结果⽂档中插⼊值到⼀个数组中$addToSet在结果⽂档中插⼊值到⼀个数组中,但数据不重复$first根据资源⽂档的排序获取第⼀个⽂档数据$last根据资源⽂档的排序获取末了⼀个⽂档数据 MongoDB 中使⽤ db.COLLECTION_NAME.aggregate([{},…]) ⽅法来构建和使⽤聚合管道,每个⽂档通过⼀个由⼀个或者多个阶段(stage)构成的管道,经过⼀系列的处理,输出相应的结果。
MongoDB的聚合管道将MongoDB⽂档在⼀个管道处理完毕后将结果通报给下⼀个管道处理。管道操纵是可以复的。
聚合框架中常⽤的⼏个操纵:

  1. db.testdb.aggregate([{$group : {_id: "$city", avgSal:{$avg:"$expectSalary"}}},{$project : {city:"$city", salary : "$avgSal"}}])
  2. db.testdb.aggregate([{$group:{_id: "$city",count:{$sum : 1}}}, {$match:{count:{$gt:1}}}])
复制代码
2.3.3 MapReduce 编程模子

Pipeline查询速率快于MapReduce,但是MapReduce的强⼤之处在于能够在多台Server上并⾏执⾏复杂的聚合逻辑。MongoDB不允许Pipeline的单个聚合操纵占⽤过多的体系内存,假如⼀个聚合操纵消耗20%以上的内存,那么MongoDB直接停⽌操纵,并向客户端输出错误消息。
MapReduce是⼀种盘算模子,简单的说就是将⼤批量的⼯作(数据)分解(MAP)执⾏,然后再将结果归并成最闭幕果(REDUCE)。
  1. db.collection.mapReduce(
  2. function() {emit(key,value);}, //map 函数
  3. function(key,values) {return reduceFunction}, //reduce 函数
  4. {
  5. out: collection,
  6. query: document,
  7. sort: document,
  8. limit: number,
  9. finalize: <function>,
  10. verbose: <boolean>
  11. }
  12. )
复制代码
使⽤ MapReduce 要实现两个函数 Map 函数和 Reduce 函数,Map 函数调⽤ emit(key, value), 遍历 collection 中所有的记载, 将 key 与 value 通报给 Reduce 函数进⾏处理。
参数说明:

  1. db.testdb.mapReduce(
  2. function() { emit(this.city,this.expectSalary); },
  3. function(key, value) {return Array.avg(value)},
  4. {
  5. query:{expectSalary:{$gt: 15000}},
  6. out:"cityAvgSal"
  7. }
  8. )
复制代码
三.索引Index

索引是⼀种单独的、物理的对数据库表中⼀列或多列的值进⾏排序的⼀种存储布局,它是某个表中⼀列或若⼲列值的集合和指向这些值数据⻚的逻辑指针清单。
索引⽬标是提⾼数据库的查询服从,没有索引的话,查询会进⾏全表扫描(scan every document in a collection),数据量⼤时严重低落了查询服从。默认环境下Mongo在⼀个集合(collection)创建时,⾃动地对集合的_id创建了唯⼀索引。
3.1 索引范例


MongoDB⽀持所有数据范例中的单个字段索引,而且可以在⽂档的任何字段上定义。
对于单个字段索引,索引键的排序顺序⽆关紧要,由于MongoDB可以在任⼀⽅向读取索引。
  1. db.集合名.createIndex({"字段名":排序⽅式})
复制代码
特殊的单键索引 逾期索引TTL(Time To Live)
TTL索引是MongoDB中⼀种特殊的索引, 可以⽀持⽂档在⼀定时间之后⾃动逾期删除,⽬前TTL索引只能在单字段上建⽴,而且字段范例必须是⽇期范例。
  1. db.集合名.createIndex({"⽇期字段":排序⽅式}, {expireAfterSeconds: 秒数})
复制代码

针对地理空间坐标数据创建索引。
2dsphere索引,⽤于存储和查找球⾯上的点
2d索引,⽤于存储和查找平⾯上的点
  1. db.company.insert(
  2. {
  3. loc : { type: "Point", coordinates: [ 116.482451, 39.914176 ] },
  4. name: "⼤望路地铁",
  5. category : "Parks"
  6. }
  7. )
  8. db.company.ensureIndex( { loc : "2dsphere" } )
  9. 参数为2dsphere 或者 2d。还可以建⽴组合索引。
  10. db.company.find({
  11. "loc" : {
  12. "$geoWithin" : {
  13. "$center":[[116.482451,39.914176],0.05]
  14. }
  15. }
  16. })
复制代码

3.2 索引管理


3.3 explain 分析

explain参数:

常见的stage的范例如下:

对于平凡查询,比力快的stage的组合(查询的时候尽可能⽤上索引):
Fetch+IDHACK
Fetch+IXSCAN
Limit+(Fetch+IXSCAN)
PROJECTION+IXSCAN
SHARDING_FITER+IXSCAN
必要优化的的stage:
COLLSCAN(全表扫描)
SORT(使⽤sort但是⽆index)
COUNT 不使⽤index进⾏count)
3.4 慢查询分析


3.5 索引底层实现原理

MongoDB 是⽂档型的数据库,它使⽤BSON 格式生存数据,⽐关系型数据库存储更⽅便。MySql是关系型数据库,数据的关联性是⾮常强的,区间访问是常⻅的⼀种环境,底层索引组织数据使⽤B+树,B+树由于数据全部存储在叶⼦节点,而且通过指针串在⼀起,如许就很容易的进⾏区间遍历甚⾄全部遍历。MongoDB使⽤B-树,所有节点都有Data域,只要找到指定索引就可以进⾏访问,单次查询从布局上来看要快于MySql。
B-树的特点:

B-树是⼀种⾃均衡的搜刮树,形式很简单:

B+树是B-树的变种,B+ 树的特点:


MongoDB和MySql的差异:

四.架构

4.1 逻辑布局

MongoDB 与 MySQL 中的架构相差不多,底层都使⽤了可插拔的存储引擎以满⾜⽤户的差别必要。⽤户可以根据程序的数据特征选择差别的存储引擎,在最新版本的 MongoDB 中使⽤了 WiredTiger 作为默认的存储引擎,WiredTiger 提供了差别粒度的并发控制和压缩机制,能够为差别种类的应⽤提供了最好的性能和存储率。
在存储引擎上层的就是 MongoDB 的数据模子和查询语⾔了,由于 MongoDB 对数据的存储与 RDBMS 有较⼤的差异,所以它创建了⼀套差别的数据模子和查询语⾔
4.2 数据模子

范例:

选择:

4.3 WiredTiger存储引擎

存储引擎是MongoDB的核⼼组件,负责管理数据怎样存储在硬盘和内存上。MongoDB⽀持的存储引擎有MMAPv1,WiredTiger和InMemory。InMemory存储引擎⽤于将数据只存储在内存中,只将少量的元数据(meta-data)和诊断⽇志(Diagnostic)存储到硬盘⽂件中,由于不必要Disk的IO操纵,就能获取所需的数据,InMemory存储引擎⼤幅度低落了数据查询的延迟(Latency)。从mongodb3.2开始默认的存储引擎是WiredTiger,3.2版本之前的默认存储引擎是MMAPv1,mongodb4.x版本不再⽀持MMAPv1存储引擎
  1. storage:
  2. journal:
  3.         enabled: true
  4. dbPath: /data/mongo/
  5. ##是否⼀个库⼀个⽂件夹
  6. directoryPerDB: true
  7. ##数据引擎
  8. engine: wiredTiger
  9. ##WT引擎配置
  10. WiredTiger:
  11.         engineConfig:
  12.                 ##WT最⼤使⽤cache(根据服务器实际情况调节)
  13.                 cacheSizeGB: 2
  14.                 ##是否将索引也按数据库名单独存储
  15.                 directoryForIndexes: true
  16.                 journalCompressor:none (默认snappy)
  17.         ##表压缩配置
  18.         collectionConfig:
  19.                 blockCompressor: zlib (默认snappy,还可选none、zlib)
  20.         ##索引配置
  21.         indexConfig:
  22.                 prefixCompression: true
复制代码
4.3.1 优势


4.3.2 ⽂件和作⽤


4.3.3 实现原理

写请求
WiredTiger的写操纵会默认写⼊ Cache ,并持久化到 WAL (Write Ahead Log),每60s或Log⽂件到达2G做⼀次 checkpoint (当然我们也可以通过在写⼊时传⼊ j: true 的参数强制 journal ⽂件的同步 ,writeConcern { w: , j: ,wtimeout: }) 产⽣快照⽂件。WiredTiger初始化时,规复⾄最新的快照状态,然后再根据WAL规复数据,保证数据的完整性。
Cache是基于BTree的,节点是⼀个page,root page是根节点,internal page是中间索引节点,leaf page真正存储数据,数据以page为单位读写。WiredTiger采⽤Copy on write的⽅式管理写操纵(insert、update、delete),写操纵会先缓存在cache⾥,持久化时,写操纵不会在原来的leaf page上进⾏,⽽是写⼊新分配的page,每次checkpoint都会产⽣⼀个新的root page。
checkpoint流程

Journaling
在数据库宕机时 , 为保证 MongoDB 中数据的持久性,MongoDB 使⽤了 Write Ahead Logging 向磁盘上的journal ⽂件预先进⾏写⼊。除了 journal ⽇志,MongoDB 还使⽤检查点(checkpoint)来保证数据的⼀致性,当数据库发⽣宕机时,我们就必要 checkpoint 和 journal ⽂件协作完成数据的规复⼯作。

五.集群⾼可⽤

5.1 主从复制架构

master-slave架构中master节点负责数据的读写,slave没有写⼊权限只负责读取数据
在主从布局中,主节点的操纵记载成为oplog(operation log)。oplog存储在体系数据库local的oplog.$main集合中,这个集合的每个⽂档都代表主节点上执⾏的⼀个操纵。从服务器会定期从主服务器中获取oplog记载,然后在本机上执⾏!对于存储oplog的集合,MongoDB采⽤的是固定集合,也就是说随着操纵过多,新的操纵会覆盖旧的操纵!
主从布局没有⾃动故障转移功能,必要指定master和slave端,不推荐在⽣产中使⽤。
mongodb4.0后不再⽀持主从复制!
5.2 复制集replica sets

复制集是由⼀组拥有雷同数据集的mongod实例做构成的集群。
复制集是⼀个集群,它是2台及2台以上的服务器构成,以及复制集成员包括Primary主节点,secondary从节点和投票节点。
复制集提供了数据的冗余备份,并在多个服务器上存储数据副本,提⾼了数据的可⽤性,保证数据的安全性。
特点:

5.2.1架构原理

⼀个复制集中Primary节点上能够完成读写操纵,Secondary节点仅能⽤于读操纵。Primary节点必要记载所有改变数据库状态的操纵,这些记载生存在 oplog 中,这个⽂件存储在 local 数据库,各个Secondary节点通过此 oplog 来复制数据并应⽤于本地,保持本地的数据与主节点的⼀致。oplog 具有幂等性,即⽆论执⾏⼏次其结果⼀致,这个比mysql 的⼆进制⽇志更好⽤。
oplog的构成布局
  1. {
  2. "ts" : Timestamp(1446011584, 2),
  3. "h" : NumberLong("1687359108795812092"),
  4. "v" : 2,
  5. "op" : "i",
  6. "ns" : "test.nosql",
  7. "o" : { "_id" : ObjectId("563062c0b085733f34ab4129"), "name" : "mongodb", "score" :"10"}
  8. }
复制代码

复制集数据同步分为初始化同步和keep复制同步。初始化同步指全量从主节点同步数据,假如Primary节点数据量⽐较⼤同步时间会⽐较⻓。⽽keep复制指初始化同步过后,节点之间的实时同步⼀般是增量同步。
初始化同步有以下两种环境会触发

MongoDB的Primary节点选举基于⼼跳触发。⼀个复制集N个节点中的任意两个节点维持⼼跳,每个节点维护其他N-1个节点的状态。
  1. ⼼跳检测:整个集群需要保持⼀定的通信才能知道哪些节点活着哪些节点挂掉。mongodb节点会向副本集中的其他节点每2秒就会发送⼀次pings包,如果其他节点在10秒钟之内没有返回就标示为不能访问。每个节点内部都会维护⼀个状态映射表,
  2. 表明当前每个节点是什么⻆⾊、⽇志时间戳等关键信息。如果主节点发现⾃⼰⽆法与⼤部分节点通讯则把⾃⼰降级为
  3. secondary只读节点。
复制代码
主节点选举触发的机会:

当触发选举时,Secondary节点尝试将⾃身选举为Primary。主节点选举是⼀个⼆阶段过程+多数派协议。

多数派协议:
发起者假如得到凌驾半数的投票,则选举通过,⾃身成为Primary节点。得到低于半数选票的缘故原由,除了常⻅的⽹络问题外,雷同优先级的节点同时通过第⼀阶段的同寅仲裁并进⼊第⼆阶段也是⼀个缘故原由。因此,当选票不⾜时,会sleep[0,1]秒内的随机时间,之后再次尝试选举。
5.3 分⽚集群 Shard Cluster

分⽚(sharding)是MongoDB⽤来将⼤型集合⽔平分割到差别服务器(或者复制集)上所采⽤的⽅法。不必要功能强⼤的⼤型盘算机就可以存储更多的数据,处理更⼤的负载
分片缘故原由

扩展方式:

5.3.1 ⼯作原理


分⽚集群由以下3个服务构成:

概念

六.安全认证

MongoDB 默认是没有账号的,可以直接连接,⽆须身份验证。
MongoDB 服务端开启安全检查之前,⾄少必要有⼀个管理员账号,admin 数据库中的⽤户都被视为管理员假如 admin 库没有任何⽤户的话,纵然在其他数据库中创建了⽤户,启⽤身份验证,默认的连接⽅式依然会有超等权限,即仍旧可以不验证账号密码还是能进⾏ CRUD,安全认证相当于⽆效。
6.1 用户相关操纵

在为库添加的用户之前要先切换到该库下

6.2 脚色


dbOwner 、userAdmin、userAdminAnyDatabase间接或直接提供了体系超等⽤户的访问
6.3 分⽚集群安全认证

和上面的操纵一样只是多一个密钥文件

七.数据备份与规复

7.1 目标


7.2 实现方式



7.3 mongodump

该命令可以导出所有数据到指定目录中。 mongodump命令可以通过参数指定导出的数据库或者集合。
  1. mongodump -h dbhost -d dbname -o dbdirectory
复制代码

  1. ./bin/mongod
  2. ump --host=192.168.211.136 --port=37017 -d local -c oplog.rs -o=/root/oplog_bak
复制代码
7.4 mongorestore

利用 mongorestore 命令来规复备份的数据。
  1. mongorestore -h <hostname><:port> -d dbname <path>
复制代码

  1. ./bin/mongorestore -h 127.0.0.1:37017 -d testdb /root/bdatas/testdb
复制代码
7.5 备份和规复的重要选项

mongodump有一个选项是 --oplog(replica set或者master/slave模式专用),
–oplog选项只对全库导出有用,所以不能指定-d选项
oplog有幂等性:已存在的数据,重做oplog不会重复;不存在的数据重做oplog就可以
  1. ./bin/mongod
  2. ump -h 127.0.0.1:37017 --oplog -o /root/bdatas
复制代码
mongorestore的–oplogReplay选项,可以重放oplog.bson中的操纵内容
–oplogLimit可以设置回放的时间节点,即此时间之前的数据规复,假设你后面有误操纵,误操纵的不规复
  1. mongorestore -h localhost:37017 --oplogReplay /root/dump
复制代码
通过 oplog 查询误操纵的末了时间
  1. /root/mongodb/bin/bsondump oplog.rs.bson | grep ""op":"d"" | head
复制代码
或者 利用
  1. db.oplog.rs.find({"op" : "d"}).sort({"ts":-1})
复制代码
  1. mongorestore -h localhost:37017 --oplogReplay --oplogLimit "1443024507:1" /root/dump/local
复制代码
7.6 定时备份



免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 IT评测·应用市场-qidao123.com (https://dis.qidao123.com/) Powered by Discuz! X3.4