前言
千里之堤毁…不对不对,千里之行,始于足下,后端的知识体系中数据库是非常重要的一环,作为一个前端而言,MongoDB可能是相对较容易学习的一个数据库了,其松散式的语法和存储方式使得学习成本没有那么高昂;
简介
MongoDB 是一个分布式文件存储的数据库,由C++语言编写的,是一个基于分布式文件存储的开源数据库系统。在高负载的情况下,添加更多的节点,可以保证服务器性能。MongoDB 旨在为WEB应用提供可扩展的高性能数据存储解决方案。
优缺点
优点
弱一致性(最终一致),更能保证用户的访问速度
举例来说,在传统的关系型数据库中,一个COUNT类型的操作会锁定数据集,这样可以保证得到“当前”情况下的较精确值。这在某些情况下,例 如通过ATM查看账户信息的时候很重要,但对于Wordnik来说,数据是不断更新和增长的,这种“较精确”的保证几乎没有任何意义,反而会产生很大的延 迟。他们需要的是一个“大约”的数字以及更快的处理速度。
文档结构的存储方式,能够更便捷的获取数据
对于一个层级式的数据结构来说,如果要将这样的数据使用扁平式的,表状的结构来保存数据,这无论是在查询还是获取数据时都十分困难。
第三方支持丰富
MongoDB社区非常活跃,很多开发框架都迅速提供了对MongDB的支持。不少知名大公司和网站也在生产环境中使用MongoDB,越来越多的创新型企业转而使用MongoDB作为和Django,RoR来搭配的技术方案。
性能优越
在使用场合下,千万级别的文档对象,近10G的数据,对有索引的ID的查询不会比mysql慢,而对非索引字段的查询,则是全面胜出。
缺点
mongodb不支持事务操作
所有事务要求严格的系统(如果银行系统)肯定不能用它。
mongodb占用空间过大
- 空间的预分配:为避免形成过多的硬盘碎片,mongodb每次空间不足时都会申请生成一大块的硬盘空间,而且申请的量从64M、128M、256M那 样的指数递增,直到2G为单个文件的较大体积。随着数据量的增加,你可以在其数据目录里看到这些整块生成容量不断递增的文件。
- 字段名所占用的空间:为了保持每个记录内的结构信息用于查询,mongodb需要把每个字段的key-value都以BSON的形式存储,如果 value域相对于key域并不大,比如存放数值型的数据,则数据的overhead是较大的。一种减少空间占用的方法是把字段名尽量取短一些,这样占用 空间就小了,但这就要求在易读性与空间占用上作为权衡了。我曾建议作者把字段名作个index,每个字段名用一个字节表示,这样就不用担心字段名取多长 了。但作者的担忧也不无道理,这种索引方式需要每次查询得到结果后把索引值跟原值作一个替换,再发送到客户端,这个替换也是挺耗费时间的。现在的实现算是 拿空间来换取时间吧。
- 删除记录不释放空间:这很容易理解,为避免记录删除后的数据的大规模挪动,原记录空间不删除,只标记“已删除”即可,以后还可以重复利用。
- 可以定期运行db.repairDatabase()来整理记录,但这个过程会比较缓慢
MongoDB没有如MySQL那样成熟的维护工具,这对于开发和IT运营都是个值得注意的地方
MongoDB适合存储一些关系简单、数据量又很大的数据,比如我们的平台上虚拟机的监控信息,包括内存、IO、CPU、网络等数据,每隔几秒就采集一次数据,每周、每月,量很大,而且旧的监控数据也不会保留太长时间,就使用的mongodb来存储这些数据;
另外mongodb的集群部署相对比较简单,易于扩展;比如主从复制,在mongo.conf配置几个参数就OK了;分片集群的配置也比较简单。还支持使用命令行来进行动态地添加和删除节点;
小结
MongoDB是一个非常不错的数据库,优缺点都非常明确
优点:
- 无模式
- 查询与索引方式灵活,是最像SQL的Nosql
- 支持复制集、主备、互为主备、自动分片等特性
缺点:
- 在集群分片中的数据分布不均匀
- 单机可靠性比较差
- 大数据量持续插入,写入性能有较大波动
- 磁盘空间占用比较大
安装
Docker安装
拉取镜像
docker pull mongo:latest
运行容器
docker run -itd --name mongo -p 27017:27017 mongo --auth
参数说明 :
-p 27017:27017 :映射容器服务的 27017 端口到宿主机的 27017 端口。外部可以直接通过 宿主机 ip:27017 访问到 mongo 的服务。
–auth:需要密码才能访问容器服务。
注意的是,如果安装在云服务器上的话需要在云服务上开启对应的安全策略,比如阿里云服务器的话。端口27017默认是没有开启的,要先进入安全策略组里,添加上端口27017。
创建用户
数据库肯定是需要用户名密码才能进入的,对吧,因此需要为数据库创建一个用户,并赋予权限。
docker exec -it mongo mongo admin
# 创建一个名为 admin,密码为 111111的用户。
> db.createUser({ user:'admin',pwd:'111111',roles:[ { role:'userAdminAnyDatabase', db: 'admin'}]});
# 尝试使用上面创建的用户信息进行连接。
> db.auth('admin', '111111')
此时的admin用户还没有读写权限,需要如下配置
权限赋予
$ mongo
> use admin
> db.createUser(
{
user: "admin",
pwd: "abc123",
roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
}
)
当运行db.stats() 或者 show users,你可能会遇到错误 not authorized on admin to execute command…
错误内容如下
> db.stats()
{
"ok" : 0,
"errmsg" : "not authorized on admin to execute command { dbstats: 1.0, scale: undefined }",
"code" : 13,
"codeName" : "Unauthorized"
}
原因是用户admin没有授予read or readWrite权限,可以如下设置
> db.auth("admin", "111111")
> db.grantRolesToUser("admin", [ { role: "readWrite", db: "admin" } ])
此时可以运行db.stats() 或者 show users,就不会出现"Unauthorized"
到这里,基本就已经安装结束了
权限说明
- 数据库用户角色:read、readWrite;
- 数据库管理角色:dbAdmin、dbOwner、userAdmin;
- 集群管理角色:clusterAdmin、clusterManager、clusterMonitor、hostManager;
- 备份恢复角色:backup、restore
- 所有数据库角色:readAnyDatabase、readWriteAnyDatabase、userAdminAnyDatabase、dbAdminAnyDatabase
- 超级用户角色:root