经常看到有人讨论,mongodb性能不如MySQL,MySQL能不能代替之类的说法,其实作为技术人,很不喜欢哪个比哪个好这种说法,基本就是挑事,我们今天一起
分别从设计思想、性能、安全性、扩展性、事务等几个方面,来做一下比较:
mongovsmysql1.设计思想的不同
以订单为例,我们看看两种数据库应该怎么设计
MySQL是这样子的
订单表
mysqlorder表结构订单详情
orderitem表结构以订单号关联字段。
MongoDB是这样子的
mongoorder结构order_item作为订单的子元素,是一个整体;
在一对一,一对多的场景,特别适合用MongoDB的内嵌文档和数组来存储,读写效率都比较高。
一对多的场景则适合MySQL的表结构来存储。
你觉得那种存储的更合理呢?
2.性能
一般情况同等条件下,MongoDB会比MySQL快,主要原因如下:
a.Mongo使用的内存映射技术,写入数据时候只要在内存里完成就可以返回给应用程序,这样并发量自然就很高。而保存到硬体的操作则在后台异步完成。
b.MongoDB的设计要求你常用的数据(workingset)可以放到内存里。这样大部分操作只需要读内存,内存操作当然比较快,这也是MongoDB,经常会和redis比较的原因。前提就是要保证服务器有足够用的内存,否则性能会严重下降。
c.数据集中存放,减少读写时磁盘寻道的时间,这也是MongoDB的基本思想之一。
并发能力,具体看过有网友测试过,MongoDB和MySQL的并发能力,借鉴一下:
并发测试结果可见,性能上并没有我们想象的差距那么大,
我没有测试过,有兴趣的网友可以测试一下
3.数据安全性
我们经常看到新闻,MongoDB数据库被黑,被勒索的新闻,为什么呢?
原来MongoDB3.6版本之前,绑定的0.0.0.0的IP,即直接外网开放,而且我们知道MongoDB默认是没有密码的,所以很多新手弄的服务器就是在裸奔,所以被黑就在所难免的,也不能全怪MongoDB。
通过一些配置,MongoDB还是很安全的
a.绑定本机IP,限于局域网访问;
b.配置防火墙,禁止外部访问和端口探测;
c.设置合理的用户和分派权限。道理和MySQL一样,遵循最小权限的原则。
4.事务
早期的版本是没有事务的,因为在MongoDB中,对于单条记录的一个操作是原子性的,一般来说,MongoDB将有关联的数据存储在一起,所以很多操作不像MySQL,需要做多表的操作。
从4.0版本开始,MongoDB支持副本集的事务,4.2支持切片的事务;
对于多表事物的需求场景,MongoDB也是支持的,可以在多个分片、库、表、文档之间实现分布式的事务。
分布式事务会严重影响性能,所以要谨慎使用,当需要事务时,优先考虑是否可通过合理使用MongoDB的内嵌文档和数组,降低使用事务的几率。
要了解MongoDB的事务,要先了解一下MongoDB的集群。
5.扩展性
随着互联网的发展,数据的量级也是撑指数的增长,从GB到TB到PB。对数据的各种操作也是愈加的困难,所以在做数据库选型时,扩展性是必须要考虑的指标:
MongoDB提供了shardedclusters(分片集群)和replicasets(副本集)两种集群模式
副本集:
架构图如下,目的是数据冗余和系统高可用,类似于MySQL的主从架构,每个节点的数据是一致的,主负责读写操作,从负责数据的备份,在需要的时候可转成主节点。
简单主从如果需要做到故障自动转移,还需要增加一个选举节点,选举节点只负责在主节点出现问题时,把从节点选举为主节点。不负责数据存储。这个和redis的哨兵模式类似。
哨兵模式关于主从的复制是一个比较复杂的过程,后面有时间再详细介绍。
分片集群:
分片是MongoDB提供的更高级的集群模式,通过分片,把数据分配到不同的机器上,每台机器只存储了部分的数据,通过mongos实现路由去访问。
切片模式架构这是MySQL没有的功能,类似于MySQL分库分表的功能,通过mycat+mysql实现
6.优势所在
MongoDB数据类型丰富,查询功能强大,还有文本搜索功能和地理空间计算,强大的数据分析和统计能力。
缺点:
没有join,连表操作能力弱,所以在复杂查询时,还是关系型数据库更胜一筹。
7.隔离级别
这是MySQL里的概念,在MongoDB事务提交前,事务外看不到本次修改的内容,隔离级别类似MySQL默认的隔离级别,“可重复读”的级别。
综上所述,总结一下。
什么时候适合用MongoDB:
1.数据结构不确定,可能发生改动的场景;
2.事务安全性要求不高,数据扩展要求较高的时候;
什么时候用MySQL:
1.有事务要求,强一致性要求较高,涉及到金钱的时候;
2.逻辑复杂,有较多join的需求;
没有最好的,只有最合适的,适合自己业务的就是最好的!
欢迎同行们讨论