CouchDB

Apache CouchDB是一个开源数据库，专注于易用性和成为"完全拥抱web的数据库"。它是一个使用JSON作为存储格式，JavaScript作为查询语言，MapReduce和HTTP作为API的面向文档的NoSQL数据库。其中一个显著的功能就是多主复制。CouchDB的第一个版本发布在2005年，在2008年成为了Apache的项目。

不同于关系型数据库，CouchDB没有将数据和关系存储在表格里。替代的，每个数据库是一个独立的文档集合。每一个文档维护其自己独立的数据和自包涵的schema。一个应用程序可能会访问多个数据库，比如其中一个位于用户的手机上，另一个位于在远程的服务器上。文档的元数据包含版本信息，让其能够合并可能因为数据库链接丢失导致的任何差异。

CouchDB实现了一个多版本并发控制（MVCC）形式，用来避免在数据库写操作的时候对文件进行加锁。冲突留给应用程序去解决。解决一个冲突的通用操作的是首先合并数据到其中一个文档，然后删除旧的数据。

其他功能包括文档级别的ACID语义和最终一致性，MapReduce，复制（Replication）。它还支持通过一个做Futon的内置web应用程序来进行数据库管理。

## 历史

CouchDB（Couch是 cluster of unreliable commodity hardware的首字母缩写）是前IBM的Lotus Notes开发者Damien Katz创建于2005年的一个项目。Damien Katz将其定义为“面向大规模可扩展对象数据库的存储系统”。他对该数据库的目标是让其成为互联网的数据库，其从底层的设计就支持部署web应用程序。他自己通过将近两年的时间创建了该项目同时将其作为开源项目在GNU General Public License下发布。

在2008年2月，其成为Apache Incubator项目，同时其许可协议变更为Apache License。几个月后，其升级为顶级项目。这促使了其第一个稳定版在2010年7月发布。

在2012年初期，Damien Katz离开了项目专注于Couchbase Server。不过该项目还在继续进行中，在2012年4月发布了1.2版本，2013年4月发布了1.3版本。

## 主要功能

文档存储：CouchDB将数据存储为“文档”，其为用JSON表示的有一个或者多个字段/值的对。字段的值可以是简单的东西比如字符串，数字，或者时间；但是数组和字典同样也可以使用。CouchDB中的每一个文档有一个唯一的id但是没有必须的文档schema。

ACID语义：CouchDB提供了ACID语义，其通过多版本并发控制的形式来实现，意味着CouchDB能够处理大量的并发读写而不会产生冲突。

Map/Reduce 视图 和 索引：存储的数据通过视图进行组装。在CouchDB中，每一个视图都是由作为map/reduce操作中的Map部分的JavaScript函数构成。该函数接受一个文档并且将其转换为一个单独的值来返回。CouchDB能够对视图进行索引，同时在文档新增，修改，删除的时候对这些索引进行更新。

支持复制的分布式架构：CouchDB的设计基于支持双向的复制（同步）和离线操作。这意味着多个复制能够对同一数据有其自己的拷贝，可以进行修改，之后将这些变更进行同步。

REST API：所有的数据都有一个唯一的通过HTTP暴露出来的URI。REST使用HTTP方法 POST，GET，PUT和DELETE来操作对应的四个基本CRUD(Create，Read，Update，Delete）操作来操作所有的资源。

最终一致性：CouchDB保证最终一致性，使其能够同时提供可用性和分割容忍。

离线支持：CoucbDB能够同步复制到可能会离线的终端设备（比如智能手机），同时当设置再次在线时处理数据同步。

CouchDB内置了一个的叫做Futon的通过web访问的管理接口。

## 使用案例、产品部署

CouchDB的复制和同步强大功能让其能够使用在无法保证网络链接但是应用程序必须继续在离线模式工作的移动设备。

### 使用CouchDB的企业

一些使用CouchDB的企业示例：

- Ubuntu，在2009年开始使用其作为同步服务“Ubuntu One” 但是在2011年停止使用。
- BBC，用在其动态内容平台。
- Credit Suisse，用在其内部的商品部门的市场框架。
- Meebo，用在其社交平台（web和应用程序），Meebo在2012年7月12日被Google收购同时被关闭。

## 数据操作

CoucbDB管理JSON文档的集合。文档通过视图进行组织。视图通过Aggregate函数进行定义，过滤查询的时候并行计算，类似MapReduce。

### 通过HTTP访问数据

应用程序通过HTTP与CouchDB进行交互。下面是一些通过cURL进行演示的示例。这些示例假设CouchDB运行在本地localhost（127.0.0.1）的5984端口。

Action｜Request｜Response

获取服务器基本信息｜`curl http://127.0.0.1:5984/`

```javascript
{
  "couchdb": "Welcome",
  "version":"1.1.0"
}
```

创建一个名为wiki的数据库｜`curl -X PUT http://127.0.0.1:5984/wiki`｜`{"ok": true}`

尝试创建第一个名为 wiki的数据库｜`curl -X PUT http://127.0.0.1:5984/wiki`

```javascript
{
  "error":"file_exists",
  "reason":"The database could not be created, the file already exists."
}
```

获取关于wiki数据库的信息｜`curl http://127.0.0.1:5984/wiki`

```javascript
{
  "db_name": "wiki",
  "doc_count": 0,
  "doc_del_count": 0,
  "update_seq": 0,
  "purge_seq": 0,
  "compact_running": false,
  "disk_size": 79,
  "instance_start_time": "1272453873691070",
  "disk_format_version": 5
}
```

删除数据库 wiki｜`curl -X DELETE http://127.0.0.1:5984/wiki`｜`{"ok": true}`

创建一个文档，请求CoudbDB来生成一个document id

```bash
curl -X POST -H "Content-Type: application/json" --data \
'{ "text" : "Wikipedia on CouchDB", "rating": 5 }' \
http://127.0.0.1:5984/wiki
```

```javascript
{
  "ok": true,
  "id": "123BAC",
  "rev": "946B7D1C"
}
```

## 开源组件

CouchDB包含了一些其他的开源项目作为其自己的内置包。

元件｜描述｜许可证

SpiderMonkey｜SpiderMonkey是一个JavaScript引擎。｜Mozilla公共许可协议

jQuery｜jQuery是一个轻量级的浏览器函式库。｜GNU通用公共许可证和MIT许可证

ICU｜ICU是成熟的开源项目。｜MIT许可证

OpenSSL｜OpenSSL是一个开源协议。实现了基本的密码功能，并提供各种实用功能。｜Apache许可证

Erlang｜Erlang是一种通用的并发编程语言和运行系统。Erlang的连续子集是函数式语言，与严格评测，单分配和动态类型。｜Mozilla公共许可协议

## 外部链接

- http://couchdb.apache.org/
- CouchDB: The Definitive Guide
- CouchDB articles on NoSQLDatabases.com
- CouchDB news and articles on myNoSQL
- Scaling CouchDB
- Complete HTTP API Reference
- Simple PHP5 library to communicate with CouchDB
- Asynchronous CouchDB client for Java
- Asynchronous CouchDB client for Scala
- 3 CouchDB Case Studies
- CouchDB for access log aggregation and analysis

## 基本资料

- 日语原文：Apache CouchDB
- 作者：Damien Katz, Jan Lehnardt, Noah Slater, Christopher Lenz, J. Chris Anderson, Paul Davis, Adam Kocoloski, Jason Davies, Benoît Chesneau, Filipe Manana, Robert Newson
- 开发者：Apache软件基金会
- 发行日期：2005
- 编程语言：Erlang
- 操作系统：跨平台
- 类型：面向文档的数据库
- 许可协议：Apache许可证