摘要
MongoDB 是一个基于分布式文件存储的数据库。由 C++ 语言编写。旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。
MongoDB是一款跨平台、面向文档的数据库。可以实现高性能、高可用性,并且能够轻松扩展,是一个基于分布式文件存储的开源数据库系统,在高负载的情况下,添加更多的节点可以保证服务器的性能。
在大数据时代中,大数据量的处理已经成了考量一个数据库最重要的原因之一。MongoDB的一个主要目标就是尽可能的让数据库保持卓越的性能,这很大程度地决定了MongoDB的设计。MongoDB选择了最大程度而利用内存资源用作缓存来换取卓越的性能,并且会自动选择速度最快的索引来进行查询。MongoDB尽可能精简数据库,将尽可能多的操作交给客户端,这种方式也是MongoDB能够保持卓越性能的原因之一。
MongoDB是非关系性数据库(NoSQL)中功能最丰富,最像关系数据库的。不采用关系模型是为了获取更好的扩展性,MongoDB不在有“行”的概念,其运行方式主要基于两个概念:集合(collection)和文档(document)。
一、Mongodb概述
1.1、特点
Mongo是一个高性能,开源,无模式的文档型数据库,它在许多场景下可用于替代传统的关系型数据库或键/值存储方式。
①面向集合的存储:适合存储对象及JSON形式的数据。
②MongoDB安装简单,提供了面向文档的存储功能,操作起来比较容易。
③MongoDB提供了复制,高可用性和自动分片功能。如果负载增加(需要更多的存储空间和更强的处理能力),它可以分布在计算机网络中的其他节点上,这就是所谓的分片。
④MongoDB支持丰富的查询表达式。
⑤高效的传统存储方式:支持二进制数据及大型对象(如照片或图片)。
1.2、适用场景
MongoDB可以为Web应用提供可扩展的高性能数据存储解决方案。MongoDB主要适用领域有网站数据、分布式场景、数据缓存和JSON文档格式存储。适合大数据量、高并发、弱事务的互联网应用,其内置的水平扩展机制提供了从几百万到十亿级别的数据处理能力,可以很好的满足Web2.0和移动互联网应用数据存储的要求。
1.3、redis和mongodb对比
MongoDB和Redis都是NoSQL,采用结构型数据存储。二者在使用场景中,存在一定的区别,这也主要由于二者在内存映射的处理过程,持久化的处理方法不同。
MongoDB建议集群部署,更多的考虑到集群方案,Redis更偏重于进程顺序写入,虽然支持集群,也仅限于主-从模式。
比较指标 | MongoDB | Redis | 比较说明 |
实现语言 | c++ | c/c++ | - |
协议 | BSON,自定义二进制 | 类telnet | - |
性能 | 依赖内存,TPS较高 | 依赖内存,TPS非常高 | Redis优于MongoDB |
可操作性 | 丰富的数据表达,索引;最类似于关系型数据库,支持丰富的查询语句 | 数据丰富,较少的IO | MongoDB优于Redis |
内存及存储 | 适合大数据量存储,依赖系统虚拟内存,采用镜像文件存储;内存占用率比较高,官方建议独立部署在64位系统 | Redis2.0后支持虚拟内存特性(VM) 突破物理内存限制;数据可以设置时效性,类似于memcache | 不同的应用场景,各有千秋 |
可用性 | 支持master-slave,replicatset(内部采用paxos选举算法,自动故障恢复),auto sharding机制,对客户端屏蔽了故障转移和切片机制 | 依赖客户端来实现分布式读写;主从复制时,每次从节点重新连接主节点都要依赖整个快照,无增量复制;不支持auto sharding,需要依赖程序设定一致性hash机制 | MongoDB优于Redis;单点问题上,MongoDB应用简单,相对用户透明,Redis比较复杂,需要客户端主动解决.(MongoDB一般使用replicasets和sharding相结合,replicasets侧重高可用性以及高可靠,sharding侧重性能,水平扩展) |
可靠性 | 从1.8版本后,采用binlog方式(类似Mysql) 支持持久化 | 依赖快照进行持久化;AOF增强可靠性;增强性的同时,影响访问性能 |
|
一致性 | 不支持事务,靠客户端保证 | 支持事务,比较脆,仅能保证事务中的操作按顺序执行 | Redis优于MongoDB |
数据分析 | 内置数据分析功能(mapreduce) | 不支持 | MongoDB优于Redis |
应用场景 | 海量数据的访问效率提升 | 较小数据量的性能和运算 | MongoDB优于Redis |
二、安装mongodb
2.1、配置官方yum源安装mongodb
1 [root@server1 ~]# cd /etc/yum.repos.d/
2 [root@server1 yum.repos.d]# vim mongodb-org.repo
3 [mongodb]
4 name=mongodb
5 baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/3.6/x86_64/
6 gpgcheck=1
7 enabled=1
8 gpgkey=https://www.mongodb.org/static/pgp/server-3.6.asc
9 [root@server1 yum.repos.d]# yum list
10 [root@server1 yum.repos.d]# yum -y install mongodb-org
2.2、修改配置文件监听地址
1 [root@server1 ~]# vim /etc/mongod.conf
2 ...省略内容
3 net:
4 port: 27017 #监听端口
5 bindIp: 0.0.0.0 #监听地址,原来是127.0.0.1,只能本地访问,换成0.0.0.0,任意都能访问
2.3、启动服务mongod.service
1 [root@server1 ~]# systemctl start mongod.service
2 [root@server1 ~]# systemctl stop firewalld.service
3 [root@server1 ~]# setenforce 0
4 [root@server1 ~]# mongo #输入mongo就进入数据库了
5 ...省略内容
6 > show dbs #查看有哪几个库
7 admin 0.000GB
8 config 0.000GB
9 local 0.000GB
三、如何配置多实例
3.1、复制配置文件以创建新实例
1 [root@server1 ~]# cd /etc/
2 [root@server1 etc]# cp -p mongod.conf mongod2.conf
3 [root@server1 etc]# vim mongod2.conf
4 ...省略内容
5 path: /data/mongodb/mongod2.log
6 dbPath: /data/mongodb/mongo
7 port: 27018
8 [root@server1 etc]# mkdir -p /data/mongodb
9 [root@server1 etc]# cd /data/mongodb/
10 [root@server1 mongodb]# touch mongod2.log
11 [root@server1 mongodb]# mkdir mongo
3.2、启动创建的实例
1 [root@lserver1 mongodb]# mongod -f /etc/mongod2.conf
2 about to fork child process, waiting until server is ready for connections.
3 forked process: 15821
4 child process started successfully, parent exiting
5 [root@server1 mongodb]# mongo --port 27018 #登录监听端口为27018的数据库
6 > db.version() #可以查看版本
7 3.6.19
四、基本操作
4.1、增删改查操作实例
1 > use school #mongodb中无需创建,直接使用(在里面创建了集合show dbs才能看到)
2 switched to db school
3 > db.createCollection('info') #在school库中创建集合info
4 { "ok" : 1 }
5 > db.info.insert({"id":1,"name":"zhangsan","score":78,"hobby":["game","sport"]}) #在集合中插入数据
6 WriteResult({ "nInserted" : 1 })
7 > db.info.find() #查看info集合中的所有内容
8 { "_id" : ObjectId("5f56e212cd5781b1ba9d5426"), "id" : 1, "name" : "zhangsan", "score" : 78, "hobby" : [ "game", "sport" ] }
9 > a=db.info.find() #创建a是db.info.find() 的别名
10 { "_id" : ObjectId("5f56e212cd5781b1ba9d5426"), "id" : 1, "name" : "zhangsan", "score" : 78, "hobby" : [ "game", "sport" ] }
11
12 > for(var i=2;i<=100;i++)db.info.insert({"id":i,"name":"jack"+i}) #利用循环一次性创建多个数据
13 WriteResult({ "nInserted" : 1 })
14 > db.info.find()
15 { "_id" : ObjectId("5f56e212cd5781b1ba9d5426"), "id" : 1, "name" : "zhangsan", "score" : 78, "hobby" : [ "game", "sport" ] }
16 { "_id" : ObjectId("5f56e319cd5781b1ba9d5427"), "id" : 2, "name" : "jack2" }
17 { "_id" : ObjectId("5f56e319cd5781b1ba9d5428"), "id" : 3, "name" : "jack3" }
18 { "_id" : ObjectId("5f56e319cd5781b1ba9d5429"), "id" : 4, "name" : "jack4" }
19 ...省略内容
20 Type "it" for more
21
22 > db.info.findOne({"id":3}) #利用关键字查找单条记录
23 { "_id" : ObjectId("5f56e319cd5781b1ba9d5428"), "id" : 3, "name" : "jack3" }
24 > a=db.info.findOne({"id":2})
25 { "_id" : ObjectId("5f56e319cd5781b1ba9d5427"), "id" : 2, "name" : "jack2" }
26 > typeof(a.id)
27 number
28 > typeof(a.name) #查看某个字段的类型
29 string
30 > db.info.update({"id":10},{$set:{"name":"tom"}}) #对id=10的记录进行修改
31 WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
32 > a=db.info.findOne({"id":10})
33 { "_id" : ObjectId("5f56e319cd5781b1ba9d542f"), "id" : 10, "name" : "tom" }
34 > db.createCollection('test')
35 { "ok" : 1 }
36 > show collections
37 info
38 test
39 > db.test.drop() #删除集合
40 true
41 > show collections #查看集合;等于show tables
42 info
43 > use myscool
44 switched to db myscool
45 > db.createCollection('test')
46 { "ok" : 1 }
47 > show dbs
48 admin 0.000GB
49 config 0.000GB
50 local 0.000GB
51 myscool 0.000GB
52 school 0.000GB
53 > db.dropDatabase() #删除库myschool,要先use myschool
54 { "dropped" : "myscool", "ok" : 1 }
55 > show dbs
56 admin 0.000GB
57 config 0.000GB
58 local 0.000GB
59 school 0.000GB
4.2、在同一实例中复制数据库
1 > db.copyDatabase("school","share") #拷贝school库,新建库名为share
2 { "ok" : 1 }
4.3、进程管理
1 > db.currentOp()
2 ...省略内容
3 "opid" : 880, #找到进程号
4 > db.killOp(880)
五、导出、导入操作
1 导出操作:
2 [root@server1 mongodb]# mongoexport -d school -c info -o /opt/school.json
3 2020-12-12T10:10:38.155+0800 connected to: localhost
4 2020-12-12T10:10:38.156+0800 exported 100 records
5 -d:指定数据库
6 -c:指定数据库中的集合
7 文件名要以.json结尾
8
9 导入操作:
10 [root@server1 mongodb]# mongoimport -d school -c test --file /opt/school.json
11 2020-12-12T10:11:56.382+0800 connected to: localhost
12 2020-12-12T10:11:56.388+0800 imported 100 documents
13
14 仅导出某一行:
15 [root@server1 mongodb]# mongoexport -d school -c info -q '{"id":{"$eq":10}}' -o /opt/test.json
六、备份与恢复数据库
6.1、备份库school
1 [root@server1 mongodb]# mongodump -d school -o /backup/
2 2020-12-12T10:16:47.324+0800 writing school.info to
3 2020-12-12T10:16:47.324+0800 writing school.test to
4 2020-12-12T10:16:47.325+0800 done dumping school.test (100 documents)
5 2020-12-12T10:16:47.325+0800 done dumping school.info (100 documents)
6 [root@server1 mongodb]# cd /backup/
7 [root@server1 backup]# ls
8 school
9 [root@server1 backup]# cd school/
10 [root@server1 school]# ls
11 info.bson info.metadata.json test.bson test.metadata.json
6.2、恢复到abc库(如果库不存在则直接创建)
1 [root@server1 school]# mongorestore -d abc --dir /backup/school/
七、实例间克隆集合
创建完27018端口的实例后进行克隆集合操作
27018端口的实例克隆2701端口的实例school库中的info集合
1 [root@server1 etc]# mongo --port 27018
2 > show dbs
3 admin 0.000GB
4 config 0.000GB
5 local 0.000GB
6 > db.runCommand({"cloneCollection":"school.info","from":"20.0.0.10:27017"})
7 { "ok" : 1 }
8 > show dbs
9 admin 0.000GB
10 config 0.000GB
11 local 0.000GB
12 school 0.000GB
13 > use school
14 switched to db school
15 > show tables #克隆成功
16 info
总结
通过Redis与Mongodb对比,可以了解非关系型数据库的优缺点,进行Mongodb的一些常规操作来快速了解Mongodb