全网最完整MongoDB 与 MySQL对比

>>强大,10k+点赞的 SpringBoot 后台管理系统竟然出了详细教程!

全网最完整MongoDB 与 MySQL对比


来源:http://r6d.cn/qGUX


NoSQL 的全称是 Not Only SQL,也可以理解非关系型的数据库,是一种新型的革命式的数据库设计方式,不过它不是为了取代传统的关系型数据库而被设计的,它们分别代表了不同的数据库设计思路。

MongoDB:
  • 它是一个内存数据库,数据都是放在内存里面的。

  • 对数据的操作大部分都在内存中,但MongoDB并不是单纯的内存数据库。-MongoDB是由C++语言进行编写的,是一个基于分布式文件存储的开源数据库系统。

  • 在高负载的情况下,天剑更多的节点,可以保证服务器的性能。

  • MongoDB旨为WEB应用提供可扩展的高性能数据存储解决方案。

MongoDB将数据存储为一个文档,将数据机构由键值(key=>value)对组成。MongoDB文档类似于JSON对象。字段值可以包含其他文档,数组及文档数组。

MongoDB的存储特点

在传统的关系型数据库中,数据是以表单为媒介进行存储的,每个表单均拥有纵向的列和横向的列。由此可见,相比较MySQL,MongoDB以一种直观文档的方式来完成数据的存储。它很像JavaScript中定义的JSON格式,不过数据在存储的时候MongoDB数据库为文档增加了序列化操作,最终存进磁盘的其实是叫做BSON的格式,即Binary-JSON。

在数据库存放的数据中,有一种特殊的键值叫做主键,它用于唯一的标识表中的某一条记录。也就是说,一个表不能有多个主键,并且主键不能为空值。

无论是MongoDB还是MySQL,都存在着主键的定义

对于MongoDB来说,其主键名叫‘_id’,如果用户不主动为其分配一个主键的话,MongoDB会自动为其生成一个随机分配的值。在MySQL中,主键的指定是MySQL插入数据时指明PRIMARY KEY来定义的。当没有指定主键的时候,另一种工具 --索引,相当于替代了主键的功能。索引可以为空,也可以有重复,另外有一种不允许重复的索引叫唯一索引。如果既没有指定主键也没有指定索引的话,MySQL会自动为数据创建一个。

  • 数据库的平均插入速率:MongoDB不指定_id插入> MySQL不指定主键插入>MySQL指定主键插入>MongoDB指定_id插入

  • 在MongoDB中,指定索引插入比不指定慢很多,这是因为,MongoDB里每一条数据的_id值都是唯一的。当不指定_id插入数据的时候,其_id是系统进行自动计算生成的。MongoDB通过计算机特征值、时间、进程ID与随机数来确保生成的_id是唯一的。而在指定_id插入时,MongoDB每插一条数据,都需要检查此_id可不可用,当数据库中数据条数太多的时候,这一步的查询开销会拖慢整个数据库的插入速度。

  • MongoDB会充分使用系统内存作为缓存,这是一种非常优秀的特征。我们测试 机的内存有64G,在插入时,MongoDB会尽可能地在内存快写不进去数据之后,再将数据持久化保存到硬盘上。这也是在不指定_id插入的时候,MongoDB的效率遥遥领先的原因。但在指定_id插入时,当数据量一大内存装不下时,MongoDB就需要将磁盘中的信息读取到内存中来查重,这样一来插入效率反而慢了。

  • MySQL不愧是一种非常稳定的数据库,无论在指定主键还是在不指定主键插入的情况下,其效率都差不了太多。

MongoDB的应用场景

在另一方面,对于开发者来说,如果是因为业务需求或者是项目初始化阶段,而是导致数据具体格式无法明确定义的话,MongoDB的这一鲜明特性就脱颖而出了。相比传统的关系型数据库,它非常容易被扩展,这也为写代码带来了极大的方便。不过MongoDB对数据之间事务关系支持比较弱,如果业务这一方面要求比较高的话,MongoDB还是并不适合此类的应用。非关系型数据库(NoSQL),属于文档型数据库 。先解释一下文档的数据库,即可以存放xml、json、bson类型系那个的数据。这些数据具备自述性(self-describing),呈现分层的树状数据结构。数据结构由键值(key=>value)对组成。

存储方式:虚拟内存+持久化
持久化方式:

MongoDB的所有数据实际上是存放在硬盘的,所有要操作的数据通过mmap的方式映射到内存某个区域内。然后,MongoDB就在这块区域里面进行数据修改,避免了零碎的硬盘操作。至于mmap上的内容flush到硬盘就是操作系统的事情了,所以,如果,MongoDB在内存中修改了数据后,mmap数据flush到硬盘之前,系统宕机了,数据就会丢失。

主要特点

  • MongoDB的提供了一个面向文档存储,操作起来比较容易和简单。

  • 可以在MongoDB记录中设置任何属性的索引(如:FirstName="Sameer",Address="8 Gandhi Road")来实现更快的排序。可以通过本地或者网络创建的数据镜像,这使得MongoDB有更强的扩展性。

  • 如果负载的增加(需要更多的存储空间和更强的处理能力),它可以分布在计算机网络中的其他节点上就是所谓的分片。

  • MongoDB支持丰富的查询表达式。查询指令使用JSON形式的标记,可轻易查询文档中内嵌的对象及数组。

  • MongoDB使用update()命令可以实现替换完成的文档(数据)或者一些指定的数据字段。

  • MongoDB中的Map/reduce主要是用来对数据进行批量处理和聚合操作。

  • Map 和 Reduce。Map 函数调用 emit(key,value) 遍历集合中所有的记录,将 key 与 value 传给 Reduce 函数进行处理。

  • Map函数和Reduce函数是使用JavaSript编写的,并可以通过db.runCommand或mapreduce命令来执行MapReduce操作。

  • GridFS是MongoDB中的一个内置功能,可以用于存放大量小文件。

  • MongoDB允许在服务端执行脚本,可以用JavaScript编写某个函数,直接在服务端执行,也可以把函数的定义存储在服务端,下次直接调用即可。

  • MongoDB支持各种编程语言:RUBY,PYTHON,JAVA,C++,PHP,C# 等多种语言。

1.它里面自带了一个名叫GridFS的分布式文件系统,这就为MongoDB的部署提供了很大的便利。而像MySQL这种比较早的数据库,虽然市面上有很多不同的分表部署方案,但这种终究不如MongoDB直接官方支持来的便捷实在。2.另外MongoDB内部还自建了对map-reduce运算框架的支持,虽然这种支持从功能上看还算是比较简单的,相当于MySQL里GroupBy功能的扩展版,怒过也为数据的统计带来了方便。3.MongoDB在启动后会将数据库中的数据以文件映射的方式加载到内存中。如果内存资源相当丰富的话,这将极大地提高数据库的查询速度,毕竟内存对I/O效率比磁盘高多了。MongoDB以BSON结构(二进制)进行存储,对海量数据存储有着明显的优势。

监控
  • MongoDB提供了网络和系统监控工具Munin,它作为一个插件应用于MongoDB中。

  • Gangila是MongoDB高性能的系统监视工具,它作为一个插件应用于MongoDB。

  • 基于图形界面的开源工具Cacti,用于查看CPU负载,网络带宽利用率,它也提供了一个应用于监控MongoDB的插件。

  • 查询语句:是独特的MongoDB的查询方式。

  • 适合场景:事件的记录,内容管理或博客平台等等。

  • 架构特点:可以通过副本集,以及分片来实现高可用。

  • 数据处理:数据是存储在硬盘上的,只不过需要经常读取的数据会被加载到内存,将数据存储在物理内存中,从而达到高速读写。

  • 成熟度与广泛度:新兴数据库,成熟度较低,No SQL数据库中最为接近关系型数据库,比较完善的DB之一,适用人群不断在增长。

MongoDB优点:
  • 性能优越:快速!在适量级的内存的MongoDB的性能是非常迅速的,它将热数据存储在物理内存中,使得热数据的读写变得十分快。

  • 高扩展:第三方支持丰富(这是与其他的No SQL相比,MongoDB也具有的优势)

  • 自身的Failover机制!

  • 弱一致性(最终一致),更能保证用户的访问速度

  • 文档结构的存储方式,能够更便捷的获取数据:json的存储格式

  • 支持大容量的存储,内置GridFS

  • 内置Sharding

MongoDB 缺点:

主要是无事务机制 ① MongoDB 不支持事务操作(最主要的缺点) ② MongoDB 占用空间过大 ③ MongoDB 没有如 MySQL 那样成熟的维护工具,这对于开发和IT运营都是个值得注意的地方

Redis:

它就是一个不折不扣的内存数据库。持久化方式:Redis 所有数据都是放在内存中的,持久化是使用 RDB 方式或者 aof 方式。

MySQL:

无论数据还是索引都存放在硬盘中。到要使用的时候才交换到内存中。能够处理远超过内存总量的数据。关系型数据库。在不同的引擎上有不同 的存储方式。查询语句是使用传统的 SQL 语句,拥有较为成熟的体系,成熟度很高。开源数据库的份额在不断增加,MySQL 的份额页在持续增长。

缺点就是在海量数据处理的时候效率会显著变慢。

数据量和性能的比较:

当物理内存够用的时候,Redis > MongoDB > MySQL 当物理内存不够用的时候,Redis 和 MongoDB 都会使用虚拟内存。实际上如果Redis要开始虚拟内存,那很明显要么加内存条,要么你就该换个数据库了。但是,MongoDB 不一样,只要,业务上能保证,冷热数据的读写比,使得热数据在物理内存中,mmap 的交换较少。MongoDB 还是能够保证性能。有人使用 MongoDB 存储了上T的数据。MySQL,MySQL根本就不需要担心数据量跟内存下的关系。不过,内存的量跟热数据的关系会极大地影响性能表现。当物理内存和虚拟内存都不够用的时候,估计除了 MySQL 你没什么好选择了。其实,从数据存储原理来看,我更倾向于将 MongoDB 归类为硬盘数据库,但是使用了 mmap 作为加速的手段而已。

简说mmap:

mmap系统调用并不是完全为了用于共享内存而设计的。它本身提供了不同于一般对普通文件的访问方式,进程可以像读写内存一样对普通文件进行操作。mmap 系统调用使得进程之间通过映射同一个普通文件实现共享内存。普通文件被映射到进程地址空间后,进程可以像访问普通内存一样对文件进行访问,不必再调用。read(),write()等操作。mmap 并不分配空间, 只是将文件映射到调用进程的地址空间里, 然后你就可以用 memcpy 等操作写文件, 而不用 write() 了.写完后用 msync() 同步一下, 你所写的内容就保存到文件里了. 不过这种方式没办法增加文件的长度, 因为要映射的长度在调用 mmap() 的时候就决定了。

MongoDB 与 MySQL 的适用场景:

MongoDB 的适用场景为:数据不是特别重要(例如通知,推送这些),数据表结构变化较为频繁,数据量特别大,数据的并发性特别高,数据结构比较特别(例如地图的位置坐标),这些情况下用 MongoDB , 其他情况就还是用 MySQL ,这样组合使用就可以达到最大的效率。

1.如果需要将 MongoDB 作为后端 db 来代替MySQL使用,即这里 MySQL 与 MongoDB 属于平行级别,那么,这样的使用可能有以下几种情况的考量:1)MongoDB 所负责部分以文档形式存储,能够有较好的代码亲和性,json 格式的直接写入方便(如日志之类) 。2)从 data models 设计阶段就将原子性考虑于其中,无需事务之类的辅助。开发用如 nodejs 之类的语言来进行开发,对开发比较方便。3)MongoDB 本身的 failover 机制,无需使用如 MHA 之类的方式实现。

2.将 MongoDB 作为类似 Redis,memcache 来做缓存db,为 MySQL 提供服务,或是后端日志收集分析。考虑到 MongoDB 属于 No SQL 型数据库,SQL 语句与数据结构不如 MySQL 那么亲和 ,也会有很多时候将 MongoDB 做为辅助MySQL 而使用的类 Redis memcache 之类的缓存db来使用。亦或是仅作日志收集分析。

MongoDB 有一个最大的缺点,就是它占用的空间很大,因为它属于典型空间换时间原则的类型。那么它的磁盘空间比普通数据库会浪费一些,而且到目前为止它还没有实现在线压缩功能,在 MongoDB 中频繁的进行数据增删改时,如果记录变了,例如数据大小发生了变化,这时候容易产生一些数据碎片,出现碎片引发的结果,一个是索引会出现性能问题。另外一个就是在一定的时间后,所占空间会莫明其妙地增大,所以要定期把数据库做修复,定期重新做索引,这样会提升MongoDB 的稳定性和效率。

1.MySQL 来自女儿的名字;MongoDB 来自 humongous 2.MySQL 使用 Table/Row/Column;MongoDB 使用 Collection/Document 3.MySQL 需要指定 table 的 schema;MongoDB的 collection 的每个 document 的 schema 可以自由修改 4.MySQL 支持 join;MongoDB 没有 join 5.MySQL 使用 SQL 语言;MongoDB 使用类似 JavaScript 的函数

命令对比

MongoDB 与 MySQL 命令对比 传统的关系数据库一般由数据库(database)、表(table)、记录(record)三个层次概念组成,MongoDB 是由数据库(database)、集合(collection)、文档对象(document)三个层次组成。MongoDB对于关系型数据库里的表,但是集合中没有列、行和关系概念,这体现了模式自由的特点。MongoDB (文档型数据库):提供可扩展的高性能数据存储 1、基于分布式文件存储 2、高负载情况下添加更多节点,可以保证服务器性能 3、将数据存储为一个文档

MongoDB 与 MySQL 的比较

1、稳定性 2、索引,索引放在内存中,能够提升随机读写的性能。如果索引不能完全放在内存,一旦出现随机读写比较高的时候,就会频繁地进行磁盘交换,MongoDB 的性能就会急剧下降 3、占用的空间很大,因为它属于典型空间换时间原则的类型。那么它的磁盘空间比普通数据库会浪费一些,而且到目前为止它还没有实现在线压缩功能, 在 MongoDB 中频繁的进行数据增删改时,如果记录变了,例如数据大小发生了变化,这时候容易产生一些数据碎片,出现碎片引发的结果, 一个是索引会出现性能问题, 另外一个就是在一定的时间后,所占空间会莫明其妙地增大,所以要定期把数据库做修复,定期重新做索引,这样会提升MongoDB 的稳定性和效率。在最新的版本里,它已经在实现在线压缩,估计应该在2.0版左右,应该能够实现在线压缩,可以在后台执行现在repair DataBase 的一些操作。如果那样,就解决了目前困扰我们的大问题。4、MongoDB 对数据间的事务关系支持比较弱 5、运维不方便

MongoDB 相对于 MySQL 的优势
  1. 适合那些对数据库具体数据格式不明确或者数据库数据格式经常变化的需求模型,而且对开发者十分友好。

  2. 自带一个分布式文件系统,可以很方便地部署到服务器机群上。MongoDB 里有一个Shard的概念,就是方便为了服务器分片使用的。每增加一台Shard,MongoDB 的插入性能也会以接近倍数的方式增长,磁盘容量也很可以很方便地扩充。

  3. 自带了对map-reduce运算框架的支持,这也很方便进行数据的统计。类似于group by MongoDB 与 MySQL 命令对比 传统的关系数据库一般由数据库(database)、表(table)、记录(record)三个层次概念组成, MongoDB 是由数据库(database)、集合(collection)、文档对象(document)三个层次组成。MongoDB 对于关系型数据库里的表,但是集合中没有列、行和关系概念,这体现了模式自由的特点。

END

推荐好文

强大,10k+点赞的 SpringBoot 后台管理系统竟然出了详细教程!

为什么MySQL不推荐使用uuid或者雪花id作为主键?

为什么建议大家使用 Linux 开发?爽(外加七个感叹号)

IntelliJ IDEA 15款 神级超级牛逼插件推荐(自用,真的超级牛逼)

炫酷,SpringBoot+Echarts实现用户访问地图可视化(附源码)

记一次由Redis分布式锁造成的重大事故,避免以后踩坑!

十分钟学会使用 Elasticsearch 优雅搭建自己的搜索系统(附源码)

全网最完整MongoDB 与 MySQL对比

原文始发于微信公众号(Java笔记虾):全网最完整MongoDB 与 MySQL对比