作者:Mani Yangkatisal
原文出处:https://severalnines.com/database-blog/battle-nosql-databases-comparing-mongodb-and-couchdb
MongoDB和CouchDB都是基于文档的NoSQL数据库。文档数据库也称为文档存储,它们通常用于存储半结构化数据的文档格式及其详细说明。它允许创建和更新程序,而无需引用主模式。内容管理和移动应用中的数据处理是可以应用文档存储的两个领域。
MongoDB概述
MongoDB是10gen的创业公司,成立于2007年。它来自文档存储家族,是典型的NoSQL,模式自由数据库,具有相对较高的性能、可伸缩性,以及丰富的数据处理能力。这个开源数据库是用C++编写的,并利用了动态模式。MongoDB的体系结构包含基于文档结构归类为集合的文档。该数据库使用BSON。BSON是JSON的二进制表示形式,并支持文档存储和数据交换。在MongoDB中,业务主题可以存储在最少数量的文档中,这些文档可以首先或次要建立索引,而无需将它们分解为多个关系文档。
除了上面提到的MongoDB能力外,它还提供了一个大型副本集集合,其中每个集合可以包含多个数据副本。在副本集中,所有主要功能(读和写)都在主要集上执行,而在前一个集出现故障的情况下使用次要集。MongoDB合并了分片,该分片可水平使用扩展过程。该文档存储数据库的负载平衡属性可以在多个服务器上运行,从而提供了数据冗余和负载均衡。此外,它还在硬件故障期间提供备份。它还利用了网格文件系统将特定文件分为不同的部分并分别存储。
MongoDB的特点:
- 数据模型设计减少了对联接的需求,并提供了模式的轻松演化。
- 高性能,因为它既不包含联接也不包含提供快速访问的事务,因此可以提高性能。
- 由于合并了副本集,因此具有很高的可用性,该副本集能够在故障期间提供备份,并且还具有很高的健壮性。
- 易于扩展。
- MongoDB的分片属性使它能够在分布式功能中快速高效地执行。这在数据的水平缩放中也是可能的。
- 查询语法非常丰富。MongoDB有自己的查询语言,称为Mongo查询语言,可以代替SQL语言。同样,utility函数和map或reduce可以代替复杂的聚合函数。
CouchDB概述
CouchDB是受Lotus Notes启发的Apache Software Foundation产品,也是基于开源文档的NoSQL数据库,主要关注易用性。它是一个单节点数据库,与其他数据库完全一样。它通常从单节点实例开始,但可以无缝升级到群集。它允许用户在许多服务器或虚拟机上运行单个数据库。与单节点CouchDB相比,CouchDB群集提供了更高的容量和可用性。它使用通用语言Erlang。像MongoDB一样,它也使用javascript和map/reduce。它以文档集合的形式而不是表形式存储数据。更新的CouchDB是无锁的,这意味着在写入过程中无需锁定数据库。该数据库中的文档还使用HTTP协议和JSON,以及将非JSON文件附加到它们的功能。因此,CouchDB与支持JSON格式的任何应用程序或软件兼容。
CouchDB的特点:
- CouchDB服务器主机名为数据库,该数据库存储数据库中具有唯一名称的文档,并且CouchDB提供RESTful HTTP API来读取和更新(添加、编辑、删除)数据库文档。
- CouchDB提供基于浏览器的GUI来处理数据、权限和配置。
- CouchDB提供了最简单的复制形式。
- CouchDB促进了身份验证和会话支持:通过Web应用程序之类的会话cookie保持身份验证处于打开状态。
- CouchDB提供数据库级别的安全性,其中每个数据库的权限分为阅读者和管理员。允许阅读者读取和写入CouchDB数据库。
- CouchDB使用身份验证将插入的数据验证到数据库中,以验证创建者和登录会话ID相同。
REST API用于写入和查询数据。它还提供文档读取、添加、编辑和删除。它使用ACID模型而不是MVCC实现的BASE。就像MongoDB在脱机时支持设备复制一样。它使用一种称为“最终一致性”的特殊复制模型。就数据而言,CouchDB是高度可靠的。单节点数据库使用仅附加的防崩溃数据结构,而多模式数据库或集群数据库可以冗余地保存数据,以便在用户需要时可以使它可用。CouchDB可以像大型群集一样扩展为全局群集,也可以像移动设备一样扩展。在任何Android或iOS设备上运行的能力使CouchDB在其他数据库中脱颖而出。
CouchDB体系结构是分布式的,它支持双向同步。它使用唯一的ID,因此不需要任何架构。尽管CouchDB遵循CAP模型的AP(可用性和分区容忍)功能,但为了克服交易的一致性,它实际上遵循了ACID模型。
CouchDB和MongoDB之间的比较
功能比较项 | CouchDB | MongoDB |
---|---|---|
数据模型 | 遵循面向文档的模型,并且数据以JSON格式显示。 | 遵循面向文档的模型,但是数据以BSON格式表示。 |
接口 | 使用基于HTTP/REST的接口。这是非常直观且设计精良的。 | 在TCP/IP上使用二进制协议和自定义协议。 |
对象存储 | 在CouchDB中,数据库包含文档。 | 在MongoDB中,数据库包含集合,而集合包含文档。 |
速度 | 读取速度对数据库至关重要,MongoDB比CouchDB快。 | MongoDB提供更快的读取速度。 |
移动端支持 | CouchDB可以在iOS和Android设备上运行,为移动设备提供支持。 | 没有提供移动端支持。 |
大小 | 数据库可以随着CouchDB一起增长。如果从一开始就没有明确定义结构,则MongoDB更适合快速增长。 | 如果我们拥有一个快速增长的数据库,MongoDB是更好的选择。 |
查询方式 | 查询使用map-reduce函数。尽管这可能是一个不错的解决方案,但对于具有传统SQL经验的人来说,学习起来可能会更加困难。 | MongoDB遵循Map/Reduce(JavaScript)创建集合+基于对象的查询语言。对于具有SQL知识的用户,MongoDB的语法更紧密,因此更易于学习。 |
备份 | 支持具有自定义冲突解决功能的主-主复制。 | 支持主-从复制。 |
并发 | 遵循MVCC(多版本并发控制)。 | 就地更新。 |
侧重点 | 可用性。 | 一致性。 |
性能一致性 | CouchDB比MongoDB更安全。 | MongoDB,数据库包含集合,而集合包含文档。 |
一致性 | CouchDB最终是一致的。 | MongoDB是高度一致的。 |
编写语言 | Erlang。 | C++。 |
分析 | 如果我们需要在移动设备上运行数据库,需要主-主复制或单服务器持久性的数据库,那么CouchDB是一个不错的选择。 | 如果我们正在寻找最大的吞吐量,或者拥有一个快速增长的数据库,那么MongoDB是您的理想之选。 |
CouchDB和MongoDB:完全不同的查询
CouchDB和MongDB是面向文档的数据存储,可与JSON文档一起使用,但是在查询时,两个数据库完全不同。CouchDB需要预定义的视图(本质上是JavaScript MapReduce函数),而MongoDB支持动态查询(基本上是常规RDBMS临时SQL查询所使用的视图)。
例如,为了使用Groovy的RESTClient在CouchDB中插入一些数据,并发布一个RESTful post,如下所示:
1import static groovyx.net.http.ContentType.JSON<font></font>
2<font></font>
3import groovyx.net.http.RESTClient<font></font>
4<font></font>
5 def client = new RESTClient("http://localhost:5498/")<font></font>
6<font></font>
7response = client.put(path: "parking_tickets/1280002020",<font></font>
8<font></font>
9 contentType: JSON,<font></font>
10<font></font>
11 requestContentType: JSON,<font></font>
12<font></font>
13 body: [officer: "Micheal Jordan",<font></font>
14<font></font>
15 location: "189 Berkely Road",<font></font>
16<font></font>
17 vehicle_plate: "KL5800",<font></font>
18<font></font>
19 offense: "Parked in no parking zone",<font></font>
20<font></font>
21 date: "2020/02/01"])
示例代码一个查询人员属性为“Micheal Jordan”的文档的函数:
1function(doc) {<font></font>
2<font></font>
3 if(doc.officer == "Micheal Jordan"){<font></font>
4<font></font>
5emit(null, doc);<font></font>
6<font></font>
7 }<font></font>
8<font></font>
9}
当我们向该视图的名称发出HTTP GET请求时,可以期望至少有一个文档如下:
1response = client.get(path: "parking_tickets/_view/by_name/officer_grey",<font></font>
2<font></font>
3 contentType: JSON, requestContentType: JSON)<font></font>
4<font></font>
5assert response.data.total_rows == 1<font></font>
6<font></font>
7response.data.rows.each{<font></font>
8<font></font>
9 assert it.value.officer == "Micheal Jordan"<font></font>
10<font></font>
11}
MongoDB的工作方式与我们通常使用普通数据库的方式非常相似:我们可以在运行时查询我们内在需求。
使用MongoDB的本机Java驱动程序插入停车票的相同实例:
1DBCollection coll = db.getCollection("parking_tickets");<font></font>
2<font></font>
3BasicDBObject doc = new BasicDBObject();<font></font>
4<font></font>
5<font></font>
6<font></font>
7doc.put("officer", "Micheal Jordan");<font></font>
8<font></font>
9doc.put("location", "189 Berkely Road ");<font></font>
10<font></font>
11doc.put("vehicle_plate", "KL5800");<font></font>
12<font></font>
13//...<font></font>
14<font></font>
15coll.insert(doc);
通过简单地在Officer属性上发起查询来查询来自Officer Micheal Jordan的MongoDB中的任何票证:
1BasicDBObject query = new BasicDBObject();<font></font>
2<font></font>
3query.put("officer", "Micheal Jordan");<font></font>
4<font></font>
5DBCursor cur = coll.find(query);<font></font>
6<font></font>
7while (cur.hasNext()) {<font></font>
8<font></font>
9 System.out.println(cur.next());<font></font>
10<font></font>
11}
结论
在本文中,我们比较了两个基于文档的NoSQL数据库——MongoDB和CouchDB。表格概述了这两个数据库之间的主要参数比较。如我们所见,项目的优先级将决定系统的选择。主要区别包括备份方法和平台支持。而且,从比较中可以明显看出,如果应用程序需要更高的效率和速度,那么MongoDB会比CouchDB更好。如果用户需要在移动设备上运行数据库,并且还需要多主复制,那么CouchDB是一个明显的选择。另外,如果数据库快速增长,MongoDB则比CouchDB更适合。使用CouchDB的主要优点是,它在移动设备(Android和iOS)上受支持,MongoDB则不行。因此,基本上讲,不同的应用程序需求将根据方案需要不同的数据库。
我们已经观察到,MongoDB比CouchDB稍好一些,因为它使用类似SQL的查询结构,在前一个查询中同样更容易。另外,对于使用动态查询,MongoDB是更好的选择。关于这两个数据库的安全性,研究仍在进行中,很难说其中哪个提供了更好且安全的环境。