CouchDB 是一個開源的面向文檔的資料庫管理系統,可以通過 RESTful JavaScript Object Notation (JSON) API 訪問。術語 “Couch” 是 “Cluster Of Unreliable Commodity Hardware” 的首字母縮寫,它反映了 CouchDB 的目標具有高度可伸縮性,提供了高可用性和高可靠性,即使運行在容易出現故障的硬體上也是如此。CouchDB 最初是用 C++ 編寫的,但在 2008 年 4 月,這個項目轉移到 Erlang OTP 平台進行容錯測試
CouchDB是用Erlang開發的面向文檔的資料庫系統,最近剛剛發布了1.0版本(2010年7月14日)。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、部落格和文檔管理系統。