一、简介
MongoDB 是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。
MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。它支持的数据结构非常松散,是类似json的bson格式,因此可以存储比较复杂的数据类型。Mongo最大的特点是它支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。
二、什么是mongodb
1.mongodb是有C++语言编写,是一个机遇分布式文件存储的开源数据库系统。
2.在高负载的情况下,随时添加更多的节点,可以保证服务器性能。
3.mongodb旨在为WEB应用提供可扩展的高性能数据存储解决方案。
4.mongodb将数据存储为一个文档,数据结构由键值(key=>value)对组成。
5.mongodb文档类似于json对象,字段值可以包含其他文档,数组及文档数组。
三、mongodb的优缺点
优点:
文档结构的存储方式,能够更便捷的获取数据
内置GridFS,支持大容量存储
海量数据下,性能优越
动态查询
全索引支持,扩展到内部对象和内嵌数组
查询记录分析
快速,就地更新
高效存储二进制大对象(照片,视频等等)
复制(副本集)和支持自动故障恢复
内置Auto-Sharding 自动分片支持云集扩展性,分片简单
MapReduce 支持复杂聚合
缺点:
不支持事务操作
MongoDB 占用空间过大 (不过这个确定对于目前快速下跌的硬盘价格来说,也不算什么缺点了)
MongoDB没有如MySQL那样成熟的维护工具
无法进行关联表查询,不适用于关系多的数据
复杂聚合操作通过mapreduce创建,速度慢
模式自由,自由灵活的文件存储格式带来的数据错
MongoDB 在你删除记录后不会在文件系统回收空间。除非你删掉数据库。但是空间没有被浪费
Ps:
1.GridFS
GridFS是一个出色的分布式文件系统,可以支持海量的数据存储。
内置了GridFS了MongoDB,能够满足对大数据集的快速范围查询。
2.内置Auto-Sharding 自动分片支持云集扩展性,分片简单
提供基于Range的Auto Sharding机制:
一个collection可按照记录的范围,分成若干个段,切分到不同的Shard上。
Shards可以和复制结合,配合Replica sets能够实现Sharding+fail-over,不同的Shard之间可以负载均衡。
查询是对客户端是透明的。客户端执行查询,统计,MapReduce等操作,这些会被MongoDB自动路由到后端的数据节点。
这让我们关注于自己的业务,适当的 时候可以无痛的升级。MongoDB的Sharding设计能力最大可支持约20 petabytes,足以支撑一般应用。
这可以保证MongoDB运行在便宜的PC服务器集群上。PC集群扩充起来非常方便并且成本很低,避免了“sharding”操作的复杂性和成本。
3、海量数据下,性能优越
在使用场合下,千万级别的文档对象,近10G的数据,对有索引的ID的查询不会比mysql慢,而对非索引字段的查询,则是全面胜出。 mysql实际无法胜任大数据量下任意字段的查询,而mongodb的查询性能实在让我惊讶。写入性能同样很令人满意,同样写入百万级别的数 据,mongodb比我以前试用过的couchdb要快得多,基本10分钟以下可以解决。补上一句,观察过程中mongodb都远算不上是CPU杀手。
4、全索引支持,扩展到内部对象和内嵌数组
索引通常能够极大的提高查询的效率,如果没有索引,MongoDB在读取数据时必须扫描集合中的每个文件并选取那些符合查询条件的记录。
这种扫描全集合的查询效率是非常低的,特别在处理大量的数据时,查询可以要花费几十秒甚至几分钟,这对网站的性能是非常致命的。
索引是特殊的数据结构,索引存储在一个易于遍历读取的数据集合中,索引是对数据库表中一列或多列的值进行排序的一种结构。
5、MapReduce 支持复杂聚合
MongoDB中聚合(aggregate)主要用于处理数据(诸如统计平均值,求和等),并返回计算后的数据结果。有点类似sql语句中的 count(*)。
与关系型数据库相比,mongodb的缺点:
Mongodb 不支持事物操作:
所以事务要求严格的系统(如果银行系统)肯定不能用它。
mongodb不支持事务操作:
所以事务要求严格的系统(如果银行系统)肯定不能用它。
mongodb占用空间过大:
关于其原因,在官方的FAQ中,提到有如下几个方面:
1、空间的预分配:为避免形成过多的硬盘碎片,mongodb每次空间不足时都会申请生成一大块的硬盘空间,而且申请的量从64M、128M、256M那 样的指数递增,直到2G为单个文件的最大体积。随着数据量的增加,你可以在其数据目录里看到这些整块生成容量不断递增的文件。
2、字段名所占用的空间:为了保持每个记录内的结构信息用于查询,mongodb需要把每个字段的key-value都以BSON的形式存储,如果 value域相对于key域并不大,比如存放数值型的数据,则数据的overhead是最大的。一种减少空间占用的方法是把字段名尽量取短一些,这样占用 空间就小了,但这就要求在易读性与空间占用上作为权衡了。
3、删除记录不释放空间:这很容易理解,为避免记录删除后的数据的大规模挪动,原记录空间不删除,只标记“已删除”即可,以后还可以重复利用。
4、可以定期运行db.repairDatabase()来整理记录,但这个过程会比较缓慢
MongoDB没有如MySQL那样成熟的维护工具,这对于开发和IT运营都是个值得注意的地方。
四、安装部署
(一)yum源方式安装
1、添加yum源
vim /etc/yum.repos.d/mongodb3.0.repo
[mongodb]
name=mongodb
baseurl=http://mirrors.aliyun.com/mongodb/yum/redhat/7Server/mongodb-org/3.2/x86_64/
http://mirrors.aliyun.com/mongodb/yum/redhat/7Server/mongodb-org/3.7/x86_64/
enabled=1
gpgcheck=0
2、安装
yum -y install mongodb-org
3、安装完的后续调整
blockdev --report
blockdev --setra 256 /dev/sda
blockdev --setra 256 /dev/dm-1
4、WARNING 解决
WARNING: /sys/kernel/mm/transparent_hugepage/enabled?is?'always'.
需要做以下操作
echo never > /sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/defrag
打开文件数限制
vim /etc/security/limits.d/20-nproc.conf(不一定是这个名称,可以cd到limits.d目录下查看)
- soft nproc 32000 //32000是mongodb要求的
5、 CentOS 7上需要把mongoDB添加到systemd,否则会出现下面的错误
systemd[1]: Failed to start SYSV: Mongo is a scalable, document-oriented database..
将mongodb添加到systemd管理中
vim /usr/lib/systemd/system/mongod.service
[Unit]
Description=mongodb database
[Service]
User=mongod
Group=mongod
Environment="OPTIONS=--quiet -f /etc/mongod.conf"
ExecStart=/usr/bin/mongod $OPTIONS run
PIDFile=/var/run/mongodb/mongod.pid
[Install]
WantedBy=multi-user.target
建立软连接
ln -s /usr/lib/systemd/system/mongod.service /etc/systemd/system/multi-user.target.wants/
重新加载systemctl
systemctl daemon-reload
6、写配置文件
vim mongodb.conf(主上的启动参数文件)
systemLog:
destination: file
logAppend: true
path: /data/mongodb/logs/mongod.log
storage:
dbPath: /data/db
journal:
enabled: true
processManagement:
net:
port: 27001
security:
authorization: enabled
7、启动
mkdir -p /data/mongodb/logs/
mongod -f mongodb.conf
(二)源码方式安装
1、下载源码包
wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-3.0.6.tgz
2、解压
tar zxf mongodb-linux-x86_64-3.0.6.tgz -C /data/
cd /data &&mv mongodb-linux-x86_64-3.0.6/ mongodb
3、添加环境变量
echo "export PATH=/data/mongodb/bin/:$PATH" >>/etc/profile
soure /etc/profile
4、创建一个默认数据保存目录
mkdir -p /data/db
mkdir -p /data/mongodb/logs/
5、添加一个配置文件
vim /etc/mongodb.conf
systemLog:
destination: file
logAppend: true
path: /data/mongodb/logs/mongod.log
storage:
dbPath: /data/db
journal:
enabled: true
processManagement:
net:
port: 27001
security:
authorization: enabled
6、启动
mongod -f mongodb.conf
Ps: Warrning 源码安装WARNING错误是一样的,请按照yum方式处理WARNING问题
五、操作使用
数据库常用命令
1、Help查看命令提示
help
db.help();
db.yourColl.help();
db.youColl.find().help();
rs.help();
2、切换/创建数据库
use yourDB; 当创建一个集合(table)的时候会自动创建当前数据库
3、查询所有数据库
show dbs;
4、删除当前使用数据库
db.dropDatabase();
5、从指定主机上克隆数据库
db.cloneDatabase(“127.0.0.1”); 将指定机器上的数据库的数据克隆到当前数据库
6、从指定的机器上复制指定数据库数据到某个数据库
db.copyDatabase("mydb", "temp", "127.0.0.1");将本机的mydb的数据复制到temp数据库中
7、修复当前数据库
db.repairDatabase();
8、查看当前使用的数据库
db.getName();
db; db和getName方法是一样的效果,都可以查询当前使用的数据库
9、显示当前db状态
db.stats();
10、当前db版本
db.version();
11、查看当前db的链接机器地址
db.getMongo();
Collection聚集集合
1、创建一个聚集集合(table)
db.createCollection(“collName”, {size: 20, capped: 5, max: 100});
2、得到指定名称的聚集集合(table)
db.getCollection("account");
3、得到当前db的所有聚集集合
db.getCollectionNames();
4、显示当前db所有聚集索引的状态
db.printCollectionStats();
用户相关
1、添加一个用户
db.addUser("name");
db.addUser("userName", "pwd123", true); 添加用户、设置密码、是否只读
2、数据库认证、安全模式
db.auth("userName", "123123");
3、显示当前所有用户
show users;
4、删除用户
db.removeUser("userName");
其他
1、查询之前的错误信息
db.getPrevError();
2、清除错误记录
db.resetError();
查看聚集集合基本信息
1、查看帮助 db.yourColl.help();
2、查询当前集合的数据条数 db.yourColl.count();
3、查看数据空间大小 db.userInfo.dataSize();
4、得到当前聚集集合所在的db db.userInfo.getDB();
5、得到当前聚集的状态 db.userInfo.stats();
6、得到聚集集合总大小 db.userInfo.totalSize();
7、聚集集合储存空间大小 db.userInfo.storageSize();
8、Shard版本信息 db.userInfo.getShardVersion()
9、聚集集合重命名 db.userInfo.renameCollection("users"); 将userInfo重命名为users
10、删除当前聚集集合 db.userInfo.drop();
聚集集合查询
1、查询所有记录
db.userInfo.find();
相当于:select* from userInfo;
默认每页显示20条记录,当显示不下的情况下,可以用it迭代命令查询下一页数据。注意:键入it命令不能带“;”
但是你可以设置每页显示数据的大小,用DBQuery.shellBatchSize= 50;这样每页就显示50条记录了。
2、查询去掉后的当前聚集集合中的某列的重复数据
db.userInfo.distinct("name");
会过滤掉name中的相同数据
相当于:select distict name from userInfo;
3、查询age = 22的记录
db.userInfo.find({"age": 22});
相当于: select * from userInfo where age = 22;
4、查询age > 22的记录
db.userInfo.find({age: {$gt: 22}});
相当于:select * from userInfo where age >22;
5、查询age < 22的记录
db.userInfo.find({age: {$lt: 22}});
相当于:select * from userInfo where age <22;
6、查询age >= 25的记录
db.userInfo.find({age: {$gte: 25}});
相当于:select * from userInfo where age >= 25;
7、查询age <= 25的记录
db.userInfo.find({age: {$lte: 25}});
8、查询age >= 23 并且 age <= 26
db.userInfo.find({age: {$gte: 23, $lte: 26}});
9、查询name中包含 mongo的数据
db.userInfo.find({name: /mongo/});
//相当于%%
select * from userInfo where name like ‘%mongo%’;
10、查询name中以mongo开头的
db.userInfo.find({name: /^mongo/});
select * from userInfo where name like ‘mongo%’;
11、查询指定列name、age数据
db.userInfo.find({}, {name: 1, age: 1});
相当于:select name, age from userInfo;
当然name也可以用true或false,当用ture的情况下河name:1效果一样,如果用false就是排除name,显示name以外的列信息。
12、查询指定列name、age数据, age > 25
db.userInfo.find({age: {$gt: 25}}, {name: 1, age: 1});
相当于:select name, age from userInfo where age >25;
13、按照年龄排序
升序:db.userInfo.find().sort({age: 1});
降序:db.userInfo.find().sort({age: -1});
14、查询name = zhangsan, age = 22的数据
db.userInfo.find({name: 'zhangsan', age: 22});
相当于:select * from userInfo where name = ‘zhangsan’ and age = ‘22’;
15、查询前5条数据
db.userInfo.find().limit(5);
相当于:selecttop 5 * from userInfo;
16、查询10条以后的数据
db.userInfo.find().skip(10);
相当于:select from userInfo where id not in (
selecttop 10 from userInfo
);
17、查询在5-10之间的数据
db.userInfo.find().limit(10).skip(5);
可用于分页,limit是pageSize,skip是第几页*pageSize
18、or与 查询
db.userInfo.find({$or: [{age: 22}, {age: 25}]});
相当于:select * from userInfo where age = 22 or age = 25;
19、查询第一条数据
db.userInfo.findOne();
相当于:selecttop 1 * from userInfo;
db.userInfo.find().limit(1);
20、查询某个结果集的记录条数
db.userInfo.find({age: {$gte: 25}}).count();
相当于:select count(*) from userInfo where age >= 20;
21、按照某列进行排序
db.userInfo.find({sex: {$exists: true}}).count();
相当于:select count(sex) from userInfo;
索引
1、创建索引
db.userInfo.ensureIndex({name: 1});
db.userInfo.ensureIndex({name: 1, ts: -1});
2、查询当前聚集集合所有索引
db.userInfo.getIndexes();
3、查看总索引记录大小
db.userInfo.totalIndexSize();
4、读取当前集合的所有index信息
db.users.reIndex();
5、删除指定索引
db.users.dropIndex("name_1");
6、删除所有索引索引
db.users.dropIndexes();
修改、添加、删除集合数据
1、添加
db.users.save({name: ‘zhangsan’, age: 25, sex: true});
添加的数据的数据列,没有固定,根据添加的数据为准
2、修改
db.users.update({age: 25}, {$set: {name: 'changeName'}}, false, true);
相当于:update users set name = ‘changeName’ where age = 25;
db.users.update({name: 'Lisi'}, {$inc: {age: 50}}, false, true);
相当于:update users set age = age + 50 where name = ‘Lisi’;
db.users.update({name: 'Lisi'}, {$inc: {age: 50}, $set: {name: 'hoho'}}, false, true);
相当于:update users set age = age + 50, name = ‘hoho’ where name = ‘Lisi’;
3、删除
db.users.remove({age: 132});
4、查询修改删除
db.users.findAndModify({
query: {age: {$gte: 25}},
sort: {age: -1},
update: {$set: {name: 'a2'}, $inc: {age: 2}},
remove: true
});
db.runCommand({ findandmodify : "users",
query: {age: {$gte: 25}},
sort: {age: -1},
update: {$set: {name: 'a2'}, $inc: {age: 2}},
remove: true
});
update 或 remove 其中一个是必须的参数; 其他参数可选。
来源:51CTO
作者:一杯老酒
链接:https://blog.51cto.com/13069301/2307282