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許可證