跳到主要内容

MongoDB

MongoDB

MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。他支持的数据结构非常松散,是类似json的bson格式,因此可以存储比较复杂的数据类型。Mongo最大的特点是他支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。

Mongo是一个高性能,开源,无模式的文档型数据库,它在许多场景下可用于替代传统的关系型数据库或键/值存储方式。

MongoDB Version4+开始原生支持事务;貌似可以替换关系数据库,但是这能行么?千万别用MongoDB?真的吗?!  我对此持保留意见。

不要为了使用MongoDB而使用MongoDB,一定要好好分析,主要精力应该放在使用Msql等关系型数据库上,当关系型数据库是在无法满足或者实现较复杂时,再去考虑这个细分场景MongoDB是否合适。

文档数据库

为了解决关系数据库 schema 带来的问题,文档数据库应运而生。文档数据库最大的特点就是 no-schema,可以存储和读取任意的数据。目前绝大部分文档数据库存储的数据格式是 JSON(或者 BSON),因为 JSON 数据是自描述的,无须在使用前定义字段,读取一个 JSON 中不存在的字段也不会导致 SQL 那样的语法错误。

文档数据库的 no-schema 特性,给业务开发带来了几个明显的优势。

  • 新增字段简单
  • 历史数据不会出错
  • 可以很容易存储复杂数据

文档数据库 no-schema 的特性带来的这些优势也是有代价的,最主要的代价就是不支持事务。文档数据库另外一个缺点就是无法实现关系数据库的 join 操作。

适用场景

  1. 网站实时数据处理。它非常适合实时的插入、更新与查询,并具备网站实时数据存储所需的复制及高度伸缩性。
  2. 缓存。由于性能很高,它适合作为信息基础设施的缓存层。在系统重启之后,由它搭建的持久化缓存层可以避免下层的数据源过载。
  3. 高伸缩性高可用的场景。MongoDB使用分片水平缩放,并且可以运行在多个服务器上,平衡负载或复制数据,以便在硬件出现故障时保持系统正常运行。
  4. 海量数据。

不适用场景

  1. 要求高度事务性的系统。
  2. 传统的商业智能应用。
  3. 复杂的跨文档(表)级联查询。

概念

db

有一些数据库名是保留的,可以直接访问这些有特殊作用的数据库。

  • admin: 从权限的角度来看,这是"root"数据库。要是将一个用户添加到这个数据库,这个用户自动继承所有数据库的权限。一些特定的服务器端命令也只能从这个数据库运行,比如列出所有的数据库或者关闭服务器。
  • local: 这个数据永远不会被复制,可以用来存储限于本地单台服务器的任意集合
  • config: 当Mongo用于分片设置时,config数据库在内部使用,用于保存分片的相关信息。

collection

数据库表/集合 集合就是 MongoDB 文档组,类似于 RDBMS (关系数据库管理系统:Relational Database Management System)中的表格。 集合存在于数据库中,集合没有固定的结构,这意味着你在对集合可以插入不同格式和类型的数据,但通常情况下我们插入集合的数据都会有一定的关联性。

document

数据记录行/文档 文档是一组键值(key-value)对(即 BSON)。MongoDB 的文档不需要设置相同的字段,并且相同的字段不需要相同的数据类型,这与关系型数据库有很大的区别,也是 MongoDB 非常突出的特点。

集群概念

mongodb集群有三种模式,主从模式,副本集模式、sharding分片模式。主从模式官网也不再推荐上生产环境,主要是安全性太低。副本集和sharding模式目前是用的最广的方案,通常这2种方案的选择通过数据量和并发数来权衡。在GB级别的基本上副本集方案可满足,TB级别或以上采用sharding模式,解决单机容量和单机并发能力。 这两种既有自己的优势也有自己的缺点,比如sharding模式分片越多,性能自然下降越多。

不是所用的使用场景都必须上集群,要因地制宜。

mongostat

#
mongostat -u admin -p Aa0123 --authenticationDatabase=admin

mongotop

#
mongotop -u admin -p Aa0123 --authenticationDatabase=admin

备份/恢复

#备份所有表
mongodump -h 172.18.92.170 --port 27017 -u 用户名 -p 密码 -o /usr/local/mongodb/bak/

#恢复所有表
mongorestore --port 27017 -u 用户名 -p 密码 --authenticationDatabase admin /usr/local/mongodb/bak/

分页查询

mongo的分页相关功能性能较差,针对这个问题经过研究发现在分页中skip数值越大性能就越低,符合条件的数据越多count性能就越低。针对这2个问题我们进行了详细的测试,共总结出2种效果不错的方案。

方案一

使用Top N的方式限制检索数量最大5000条,例如统计符合条件的报警记录条数:

db.AlarmHistory.find({
"did": {$in: [
"10000000000000001000"
]},
"createTime":{ "$gte":1636949672, "$lt":1637381672}
}).limit(5000).count(true);

通过limit(5000)限制统计最大值即为5000,从而提高了count效率,但也有一些局限性就是只能统计符合条件的最后5000条数据,而不是符合条件的全部数据。

方案二

通过加载更多的方式分页,即查询下一页时需要传递当前页的最后一条数据的序号,这样就绕过count统计,但这种方式的弊端在于页面不会显示总共多少条数据、共分多少页等数据。

参考

  1. MongoDB教程