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 体系结构
| RDBMS | MongoDB |
|---|---|
| database(数据库) | 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) | GridFS ⽤两个集合来存储⼀个⽂件:fs.files与fs.chunks 真正存储需要使⽤mongofiles -d gridfs put song.mp3 |
1.4 适⽤场景
适用场景:
- ⽹站数据:Mongo ⾮常适合实时的插⼊,更新与查询,并具备⽹站实时数据存储所需的复制及⾼度伸缩性。
- 缓存:由于性能很⾼,Mongo 也适合作为信息基础设施的缓存层。在系统重启之后,由Mongo 搭建的持久化缓存层可以避免下层的数据源过载
- ⼤尺⼨、低价值的数据:使⽤传统的关系型数据库存储⼀些⼤尺⼨低价值数据时会⽐较浪费,在此之前,很多时候程序员往往会选择传统的⽂件进⾏存储。
- ⾼伸缩性的场景:Mongo ⾮常适合由数⼗或数百台服务器组成的数据库,Mongo 的路线图中已经包含对MapReduce 引擎的内置⽀持以及集群⾼可⽤的解决⽅案。
- ⽤于对象及JSON 数据的存储:Mongo 的BSON 数据格式⾮常适合⽂档化格式的存储及查询
具体应⽤场景:
-
游戏场景
使⽤ MongoDB 存储游戏⽤户信息,⽤户的装备、积分等直接以内嵌⽂档的形式存储,⽅便查询、更新。
-
物流场景
使⽤ MongoDB 存储订单信息,订单状态在运送过程中会不断更新,以 MongoDB 内嵌数组的形式来存储,⼀次查询就能将订单所有的变更读取出来。
-
社交场景
使⽤ MongoDB 存储存储⽤户信息,以及⽤户发表的朋友圈信息,通过地理位置索引实现附近的⼈、地点等功能。
-
物联⽹场景
使⽤ MongoDB 存储所有接⼊的智能设备信息,以及设备汇报的⽇志信息,并对这些信息进⾏多维度的分析。
-
直播
使⽤ MongoDB 存储⽤户信息、礼物信息等。
应⽤特征:
- 应⽤必须不需要事务及复杂 join ⽀持
- 新应⽤,需求会变,数据模型⽆法确定,想快速迭代开发
- 应⽤需要2000-3000以上的读写QPS(更⾼也可以)
- 应⽤需要TB甚⾄ PB 级别数据存储
- 应⽤发展迅速,需要能快速⽔平扩展
- 应⽤要求存储的数据不丢失
- 应⽤需要99.999%⾼可⽤
- 应⽤需要⼤量的地理位置查询、⽂本查询
1.5 搭建
去官网下载社区版,本文用的MongoDB 4.2.24,机器是mac,然后将压缩包解压即可
1.5.1 单机
-
cd到解压路径下
-
创建一个保存数据的目录(mongo/data)
-
单机启动:
./bin/mongod
-
指定配置⽂件⽅式的启动
./bin/mongod -f mongo.conf
-
配置⽂件样例
#数据库⽬录 dbpath=mongo/data/ #监听的端⼝ port=27017 # 监听IP地址,默认全部可以访问 bind_ip=0.0.0.0 #是否以后台启动的⽅式启动 fork=true #⽇志路径 logpath = mongo/data/MongoDB.log #是否追加⽇志 logappend = true #是开启⽤户密码登陆 auth=false
-
shell 的启动
#启动mongo shell ./bin/mongo #指定主机和端⼝的⽅式启动 ./bin/mongo --host=主机IP --port=端⼝
1.5.2 复制集
-
cd到解压路径下
-
创建三个保存数据的目录(mongo/data/server1、mongo/data/server2、mongo/data/server3)
-
新建三个conf文件,命名分别是mongo_27017、mongo_27018、mongo_27019
-
mongo_27017.conf
# 主节点配置 dbpath=mongo/data/server1 bind_ip=0.0.0.0 port=27017 fork=true logpath=/data/mongo/logs/server1.log replSet=testReplicaRets
-
mongo_27018.conf
# 主节点配置 dbpath=mongo/data/server2 bind_ip=0.0.0.0 port=27018 fork=true logpath=/data/mongo/logs/server2.log replSet=testReplicaRets
-
mongo_27019.conf
# 主节点配置 dbpath=mongo/data/server3 bind_ip=0.0.0.0 port=27019 fork=true logpath=/data/mongo/logs/server3.log replSet=testReplicaRets
-
启动
./bin/mongod -f mongo_27017.conf ./bin/mongod -f mongo_27018.conf ./bin/mongod -f mongo_27019.conf
-
随便进入一个节点,进行初始化
var cfg ={"_id":"testReplicaRets", "protocolVersion" : 1, "members":[ {"_id":1,"host":"localhost:27017","priority":10}, {"_id":2,"host":"localhost:27018"}, {"_id":3,"host":"localhost:27019"}, ] } rs.initiate(cfg) rs.status() -
节点的动态增删
增加节点 rs.add("localhost:27019") 删除slave 节点 rs.remove("localhost:27019") -
仲裁节点动态增删
rs.addArb("localhost:37020")复制集成员的配置参数
参数字段 类型说明 取值 说明 _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 分片集群
-
配置config节点集群
-
创建好各个配置节点需要的目录
-
配置conf文件
-
config_37017.conf
dbpath=config_37017 port=37017 bind_ip=0.0.0.0 fork=true logpath = config_37017/config.log logappend = true auth=false replSet=testConfig configsvr=true
-
config_37018.conf
dbpath=config_37018 port=37017 bind_ip=0.0.0.0 fork=true logpath = config_37018/config.log logappend = true auth=false replSet=testConfig configsvr=true
-
config_37019.conf
dbpath=config_37019 port=37017 bind_ip=0.0.0.0 fork=true logpath = config_37019/config.log logappend = true auth=false replSet=testConfig configsvr=true
-
启动
./bin/mongod -f config/config_37017.conf ./bin/mongod -f config/config_37018.conf ./bin/mongod -f config/config_37019.conf
-
初始化,要切换到admin库下
use admin var cfg ={"_id":"testConfig", "members":[ {"_id":1,"host":"localhost:37017"}, {"_id":2,"host":"localhost:37018"}, {"_id":3,"host":"localhost:37019"}] }; rs.initiate(cfg) -
配置shard(分片)节点集群
-
创建节点需要的目录
-
配置conf文件
和配置复制集一样,只不过要在配置文件中加上
shardsvr=true
-
启动
#分片1 ./bin/mongod -f config/mongo_27018.conf ./bin/mongod -f config/mongo_27019.conf ./bin/mongod -f config/mongo_27020.conf #分片2 ./bin/mongod -f config/mongo_27021.conf ./bin/mongod -f config/mongo_27022.conf ./bin/mongod -f config/mongo_27023.conf
-
初始化
进入某个分片集群任意节点对该集群进行初始化
#分片1 var cfg ={"_id":"shard1", "protocolVersion" : 1, "members":[ {"_id":1,"host":"localhost:27020"}, {"_id":2,"host":"localhost:27018"}, {"_id":3,"host":"localhost:27019","arbiterOnly":true} ] }; rs.initiate(cfg) rs.reconfig(cfg) rs.status() #分片2 var cfg ={"_id":"shard2", "protocolVersion" : 1, "members":[ {"_id":1,"host":"localhost:27023"}, {"_id":2,"host":"localhost:27021"} {"_id":3,"host":"localhost:27022","arbiterOnly":true} ] } rs.initiate(cfg) rs.reconfig(cfg) rs.status() -
配置路由节点
-
创建节点需要的目录
-
配置conf文件
和配置单机启动时一样,只不过要在配置文件中加上
configdb=testConfig/localhost:37017,localhost:37018,localhost:37019
-
启动
./bin/mongos -f route/route_27017.conf
-
为路由添加分⽚节点
进⼊路由mongos
sh.status() sh.addShard("shard1/localhost:27018,localhost:27019,localhost:27020"); sh.addShard("shard1/localhost:27021,localhost:27022,localhost:27023"); sh.status() -
指定⽚键
进⼊路由mongos
为数据库开启分⽚功能
sh.enableSharding("testdb")为指定集合开启分⽚功能
sh.shardCollection("testdb.test_datas",{"⽚键字段名如name":索引说明,如hashed})二.命令
2.1 基本操作
查看数据库:show dbs; 切换数据库 如果没有对应的数据库则创建:use 数据库名; 创建集合:db.createCollection("集合名") 查看集合:show tables;或show collections; 删除集合:db.集合名.drop(); 删除当前数据库:db.dropDatabase()2.2 CURD
2.2.1 插入
单条:db.集合名.insertOne(BSON)
db.testdb.insertOne({name:"张晓峰",birthday:new ISODate("2000-07-01"),gender:1,expectSalary:15000,city:"bj"})多条:db.集合名.insertMany([BSON,BSON])
db.testdb.insertMany( [{name:"李丽",birthday:new Date("1996-05-01 14:20:09"),gender:0,expectSalary:21000,city:"sz"}, {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 字段名 data/mongodb/testKeyFile.file chmod 600 data/mongodb/keyfile/testKeyFile.file 配置节点集群和分⽚节点集群开启安全认证和指定密钥⽂件
auth=true keyFile=data/mongodb/testKeyFile.file
在路由配置⽂件中 设置密钥⽂件
keyFile=data/mongodb/testKeyFile.file
七.数据备份与恢复
7.1 目的
- 防止硬件故障引起的数据丢失
- 防止人为错误误删数据
- 时间回溯
- 监管要求
7.2 实现方式
- 文件系统快照
- 复制数据文件
- mongodump
7.3 mongodump
该命令可以导出所有数据到指定目录中。 mongodump命令可以通过参数指定导出的数据库或者集合。
mongodump -h dbhost -d dbname -o dbdirectory
-
-h:MongoDB所在服务器地址,例如:127.0.0.1或者127.0.0.1:37017
-
–db 或者 -d :需要备份的数据库,例如:testdb
-
–out 或者-o:备份的数据存放位置,例如:/root/bdatas 在备份完成后,系统自动在root目录下建立一个bdatas目录,这个目录里面存放该数据库实例的备份数据。
-
-c :和-d 一起使用,备份指定数据库的指定集合
./bin/mongodump --host=192.168.211.136 --port=37017 -d local -c oplog.rs -o=/root/oplog_bak
7.4 mongorestore
使用 mongorestore 命令来恢复备份的数据。
mongorestore -h -d dbname
-
–host , -h :
MongoDB所在服务器地址,默认为: localhost:37017
-
–db 或者 -d :
需要恢复的数据库,例如:testdb,这个名称也可以和备份时候的不一样
-
–drop:
恢复的时候,先删除当前数据,然后恢复备份的数据。
-
mongorestore:
设置备份数据所在位置,例如:/root/bdatas/testdb
不能同时指定–dir 选项,–dir也可以设置备份目录。
注意: 恢复指定的数据库 需要在恢复的路径中出现数据库的名字
-
–dir:
指定备份的目录
./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就可以
./bin/mongodump -h 127.0.0.1:37017 --oplog -o /root/bdatas
mongorestore的–oplogReplay选项,可以重放oplog.bson中的操作内容
–oplogLimit可以设置回放的时间节点,即此时间之前的数据恢复,假设你后面有误操作,误操作的不恢复
mongorestore -h localhost:37017 --oplogReplay /root/dump
通过 oplog 查询误操作的最后时间
/root/mongodb/bin/bsondump oplog.rs.bson | grep ""op":"d"" | head
或者 使用
db.oplog.rs.find({"op" : "d"}).sort({"ts":-1})mongorestore -h localhost:37017 --oplogReplay --oplogLimit "1443024507:1" /root/dump/local
7.6 定时备份
-
准备备份目录
mkdir -p /root/backup/mongod_bak/mongod_bak_now /root/backup/mongod_bak/mongod_bak_list
-
编写备份脚本
vi /root/backup/mongobk.sh
#!/bin/sh # dump 命令执行路径,根据mongodb安装路径而定 DUMP=/root/mongodb/bin/mongodump # 临时备份路径 OUT_DIR=/root/backup/mongod_bak/mongod_bak_now # 压缩后的备份存放路径 TAR_DIR=/root/backup/mongod_bak/mongod_bak_list # 当前系统时间 DATE=`date +%Y_%m_%d%H%M%S` # 数据库账号 # DB_USER=user # 数据库密码 # DB_PASS=password # 代表删除7天前的备份,即只保留近 7 天的备份 DAYS=7 # 最终保存的数据库备份文件 TAR_BAK="mongod_bak_$DATE.tar.gz" cd $OUT_DIR rm -rf $OUT_DIR/* mkdir -p $OUT_DIR/$DATE $DUMP -h 127.0.0.1 --port 37017 -o $OUT_DIR/$DATE # 压缩格式为 .tar.gz 格式 tar -zPcvf $TAR_DIR/$TAR_BAK $OUT_DIR/$DATE # 删除 7 天前的备份文件 find $TAR_DIR/ -mtime +$DAYS -delete exit
-
修改脚本权限
chmod +x /root/backup/mongobk.sh
-
编辑crontab
crontab -e
#表示每天凌晨2点30执行备份 30 2 * * * /root/backup/mongobk.sh
-
查看crontab 的状态
service crond status
-
如果没有启动 可以使用下面的命令 启动定时服务 和加入开机自启动
# 启动定时任务 service crond start # 加入开机自动启动 chkconfig --level 35 crond on
-
查看定时任务和删除定时任务
crontab -l crontab -r crontab -e
-
-
-
-
-
-
-
-
-
-
-


