CouchDB 是一个开源的面向文档的数据库管理系统,可以通过 RESTful JavaScript Object Notation (JSON) API 访问。术语 “Couch” 是 “Cluster Of Unreliable Commodity Hardware” 的首字母缩写,它反映了 CouchDB 的目标具有高度可伸缩性,提供了高可用性和高可靠性,即使运行在容易出现故障的硬件上也是如此。CouchDB 最初是用
C++ 编写的,但在 2008 年 4 月,这个项目转移到 Erlang OTP 平台进行容错测试
简介
CouchDB是用
Erlang开发的面向文档的
数据库系统,2010年7月14日发布了1.0版本。CouchDB不是一个传统的关系数据库,而是面向文档的数据库,其数据存储方式有点类似
lucene的index文件格式,CouchDB最大的意义在于它是一个面向web应用的新一代
存储系统,事实上,CouchDB的口号就是:下一代的Web应用存储系统。
CouchDB 可以安装在大部分 POSIX 系统上,包括 Linux® 和 Mac OS X。Version 2.2.0开始正式支持Windows (x64)。CouchDB 可以从源文件安装,也可以使用包管理器安装(比如在 Mac OS X 上使用 MacPorts)。
CouchDB 是一个顶级 Apache Software Foundation 开源项目,根据 Apache 许可 V2.0 发布。这个开源许可允许在其他软件中使用这些源代码,并根据需要进行修改,但前提是遵从版权需知和免责声明。与许多其他开源许可一样,这个许可允许用户根据需求使用、修改和分发该软件。不一定由同一个许可包含所有修改,因为我们仅维护一个 Apache 代码使用许可需知。
数据特点
一、CouchDB是分布式的数据库,他可以把
存储系统分布到n台物理的节点上面,并且很好的协调和同步节点之间的数据读写一致性。这当然也得靠Erlang无与伦比的并发特性才能做到。对于基于web的大规模应用文档应用,分布式可以让它不必像传统的关系数据库那样分库拆表,在应用代码层进行大量的改动。
二、CouchDB是面向文档的数据库,存储半结构化的数据,比较类似
lucene的index结构,特别适合存储文档,因此很适合CMS,电话本,地址本等应用,在这些应用场合,
文档数据库要比关系数据库更加方便,性能更好。
三、CouchDB支持REST API,可以让用户使用
JavaScript来操作CouchDB数据库,也可以用JavaScript编写查询语句,我们可以想像一下,用
AJAX技术结合CouchDB开发出来的CMS系统会是多么的简单和方便。
其实CouchDB只是Erlang应用的冰山一角,在最近几年,基于Erlang的应用也得到的蓬勃的发展,特别是在基于web的大规模,分布式应用领域,几乎都是Erlang的优势项目。
工作原理
CouchDB 构建在强大的 B-树储存引擎之上。这种引擎负责对 CouchDB 中的数据进行排序,并提供一种能够在对数均摊时间内执行搜索、插入和删除操作的机制。CouchDB 将这个引擎用于所有内部数据、文档和视图。
因为 CouchDB 数据库的结构独立于模式,所以它依赖于使用视图创建文档之间的任意关系,以及提供聚合和报告特性。使用 Map/Reduce 计算这些视图的结果,Map/Reduce 是一种使用分布式计算来处理和生成大型数据集的模型。Map/Reduce 模型由 Google 引入,可分为 Map 和 Reduce 两个步骤。在 Map 步骤中,由主节点接收文档并将问题划分为多个子问题。然后将这些子问题发布给工作节点,由它处理后再将结果返回给主节点。在 Reduce 步骤,主节点接收来自工作节点的结果并合并它们,以获得能够解决最初问题的总体结果和答案。
CouchDB 中的 Map/Reduce 特性生成键/值对,CouchDB 将它们插入到 B-树引擎中并根据它们的键进行排序。这就能通过键进行高效查找,并且提高 B-树中的操作的性能。此外,这还意味着可以在多个节点上对数据进行分区,而不需要单独查询每个节点。
传统的关系数据库管理系统有时使用锁来管理并发性,从而防止其他客户机访问某个客户机正在更新的数据。这就防止多个客户机同时更改相同的数据,但对于多个客户机同时使用一个系统的情况,数据库在确定哪个客户机应该接收锁并维护锁队列的次序时会遇到困难,这很常见。在 CouchDB 中没有锁机制,它使用的是多版本并发性控制(Multiversion concurrency controlMVCC)— 它向每个客户机提供数据库的最新版本的快照。这意味着在提交事务之前,其他用户不能看到更改。许多现代数据库开始从锁机制前移到 MVCC,包括 Oracle(V7 之后)和 Microsoft® SQL Server 2005 及更新版本。
使用体验
面向文档数据库,不需要范式,直接存储JSON就可以,CouchDB默认会生成 _id,_rev 两个键,_id是一条记录(文档)的唯一标识,如果不提供_id,_id会自动生成,也可以手动指定_id,比如用手机号做主键:
{'_id':'+86186*****',name:''}
_rev是其版本号,每更新一次 _rev就会自动发生变化,格式为
5-6a8617596d2adfea245662df0df611ao
,标识第5个版本,后面是HASH签名,可以通过_rev寻找到所有的历史版本,所以用来做需要存储版本的文档系统应该非常不错,比如多人协作修改一篇文档等应用。
数据库区别
面向文档的数据库和关系数据库之间的区别
对很多人而言,刚接触面向文档数据库管理系统这个概念时很难理解它,尤其是长期与关系数据库打交道的人员。这是因为这两个模型相似的地方很少。
顾名思义,面向文档数据库是由一系列自包含的文档组成的。这意味着相关文档的所有数据都储存在该文档中 — 而不是关系数据库的关系表中。事实上,面向文档的数据库中根本不存在表、行、列或关系。这意味着它们是与模式无关的;不需要在实际使用数据库之前定义严格的模式。如果某个文档需要添加一个新字段,它仅需包含该字段,从而不影响到数据库中的其他文档。因此,文档不必为没有值的字段储存空数据值。
即将推出的书CouchDB: The Definitive Guide使用名片作为 “现实的文档”,并介绍了与关系数据库相比,如何在面向文档的数据库中描述它。在关系数据库中,您需要使用 4 个以上的表来储存这些数据:一个 “Person” 表、一个 “Company” 表、一个 “Contact Details” 表和一个用于储存名片本身的表。这些表都有严格定义的列和键,并且使用一系列的连接(join)组装数据。
虽然这样做的优势是每段数据都有一个惟一真实的版本,但这为以后的修改带来不便。此外,也不能修改其中的记录以用于不同的环境。例如,一个人可能有传真号码,而另一个人没有。在名片上不应该显示 “传真:没有”,而是忽略任何关于传真的细节。
在面向文档的数据库中,每个名片都储存在各自的文档中,并且每个文档都可以定义它需要使用的字段。因此,对于没有传真号码的人而言,就不需要定义传真的值,而对于有传真号码的人,则根据他们的意愿定义该值。
这两种数据库的另一个不同点是惟一标识符的储存。在关系数据库中通常可以使用主键,它由一个自动递增特性或序列生成器生成。当然,这些标识符仅相对于所使用的表或数据库是惟一的 — 其他表或数据库还可以使用它们。如果同时对不同网络上的两个数据库执行更新操作,这两个数据库不会同时准确地获取下一个惟一标识符。CouchDB 没有自动递增或序列特性。相反,它为每个文档分配一个通用惟一标识符(Universally Unique Identifier,UUID),这就杜绝了其他数据库意外地选择相同的惟一标识符的情况。
面向文档数据库和关系数据库的另一个重要区别就是面向文档数据库不支持连接。因此 CouchDB 中没有主键和外键,没有基于连接的键。这并不意味着不能从 CouchDB 数据库获取一组关系数据。一个称为视图的特性允许您为没有在数据库中定义的文档创建一种任意关系。这意味着您能够获得典型的 SQL 联合查询的所有好处,但又不需要在数据库层预定义它们的关系。
一定要注意,虽然面向文档数据库的操作方式不同于关系数据库,但这并不意味着它们是可以替换的。CouchDB 的目的并不是替换关系数据库,而是为那些更适合使用面向文档模型(而不是传统的关系数据模型)的项目提供一种选择,比如 wikis、博客和文档管理系统。