作為 NoSQL 潮流中的一份子,很容易被拿來與被貼上一樣標籤 (buzzwords) 的資料庫作為比較。各個專案分別被貼上 key-value stores, tuple stores, BigTable Clones, Document store, Graph database 等等標籤

這些標籤分類有時很容易幫助使用者瞭解大概的後段實做技術屬性,但很多時候,也會把使用者帶來偏頗預設看法與錯誤理解。我們可以說這些新技術都是想解決 CAP theorem 問題,但其實這些不同的資料庫計劃各有其想要解決的問題與開發哲學,如果以概括性的功能特徵來作為選擇技術的方式,很多時候會發現專案發展方向適合自己需求。使用者應該先定義自己的問題後,再依照選擇最適合的專案屬性。

Mikeal Rogers (CouchOne 的開發者) 上個月就,這波產業浪潮掩蓋了各專案實際要解決的問題,取而代之是對於 Big Data 的想像與期待。Mikeal 那麼就讓其他人 (與舊資料庫業者) 去追尋 NoSQL 的浪潮吧,CouchDB 可以專注與處理 Mobile Database

CouchDB 特色

試用了 CouchDB 一陣子,幾個特別欣賞的特色功能:

  • Implemention for ACID Properties
  • Schema-Free document-oriented database
  • RESTful JSON API
  • View model / JavaScript View Functions
  • Replication (Peer-based distributed databases), Distributed, featuring robust, incremental replication with bi-directional conflict detection and management.

CouchDB 使用 MVCC model,所有的資料庫寫入 (add, update, delete) 都不需要先 lock 資料庫,因此可以保證可以即時讀出資料。索引則是靠 B-Tree 大量存於硬碟,Document 一份索引,每一份 View (利用 MapReduce pattern 設計的查詢界面) 也會存有一份索引,因此你的資料庫會佔用有大量硬碟空間來換取速度。

另外則是資料可以是隨意的 Json document, 所以愛存什麼就存什麼。此外 API 界面是 RESTful,加上內建 Javascript 的 View Server,你可以用內建的 Show 功能 Render Document, CouchApp 很方便配合瀏覽器使用 (也支援權限功能)。

最重要的特色是 Replication 功能,CouchDB 支援雙向衝突偵測,很方便長期離線的 Client 上線後快速同步資料庫內容,平時離綫狀態,也可以存取已經拉回的資料。

CouchDB 目前限制

雖說 CouchDB 使用 MVCC Model,但 CouchDB 的讀寫速度遠遠慢於 in-memory key-value,與 MySQL 評測也未能夠勝出。加上 CouchDB 只支援 Replication,要作 Horizontal partitioning 要靠 CouchDB Lounge,同等於手動作 Sharding. 效能跟彈性都未能夠勝過其他資料庫系統。

此外,作為存取 unstructured data 的代價,你若想要查詢特別資料,必須依賴 View Model,每組 View 會建出獨立的 b-tree index,這種索引的代價頗高,特別是你想做 ad hoc query 時,使用 _temp_view 會浪費你大量的磁碟與 CPU。因此你必須設計軟體時與鍵入資料前先建好 View。

雖然 View functions 用了 MapReduce pattern, 但礙於 CouchDB View API 的限制,目前很難作多次的資料處理,基本上一次 View 倒出來的資料僅限制一次查詢,你無法方便快速的做第二次 Map/Reduce 處理,如此缺乏彈形讓 MapReduce 反而像是限制,而非一種特色。

除了 Big Data 以外相關應用

捨去上述限制不談,CouchDB 的特色仍然可以作很多應用,特別是 JSON API 與 Peer-based distributed 這兩個功能,很方便在 Laptop 或 Mobile devices 上提供一些應用,特別是你需要在時常離綫的裝置上處理伺服器與本地端資料時。

除了像是 CouchOne 推出相容 CouchDB 的 CouchOne Mobile for Android。在 Linux 上則有 Desktop Couch,目前整合了 Tomboy, Evolution, Bindwood for Firefox 等,可以用來管理 PIM, Bookmarks 等等。理論上可以整合 UbuntuOneMidgard

我讀過兩本 CouchDB 得書籍CouchDB: The Definitive Guide 1st Edition 與 Beginning CouchDB,比較推薦 Beginning CouchDB,但 CouchDB: The Definitive Guide 的下一版,內容已經有改善。

本文是個人使用經驗與看法,如果錯誤,歡迎指教。

長久以來,一直為了一個小小的資料庫系統尋找適合的解決方案。這個系統的基本概念是要建立一個可以大量收集與處理 Metadata 的資料模型。由於這只是一個 Pet Project,在無法額外投資建立叢集系統的狀況下,只能試著用一些簡單的方式來實做。

這個資料庫的用途是可利用透過各式 Metadata 所組成的 Facts 進行推論。稍早的實驗,已經可以有效率的進行基本的前推式(Forward-chaining)與回溯式(Backward-chaining)的混合式推導來取出有意義的「knowledge」。

我的資料形式都是 subject-predicate-object 表示的 RDF Triples (RDF: Concepts and Abstract Syntax),原本是專注在可以處理 RDFTriplestore,但大部份的開放原碼後端資料庫都還是使用 RDBMS,加上冗贅的 RDF/XML 資料交換格式,速度上實在難以令人忍受。而 ORDBMS 又需要使用不少的計算資源 (記憶體 :-/ ) 才能順利執行。

於是,策略性的將系統設計為 Controlled vocabulary,後端採用飛速的 SQlite。以速度來說,在有 VFS 快取下,從兩千餘萬筆資料中取出十筆的時間大約是 150ms。這種速度在使用上是毫無問題的,但如此一來毫無 Scalability 可言。問題之一是寫入的速度並不快,而且寫入過程資料庫便被鎖住,別說同時寫入,就是取用也是一個大問題。

於是,試著找一些可行的方案,如以 BigTable 為基礎的 Apache HBase, Hypertable,或是 Document-oriented database 類型的各式解決方案,如以 Erlang 開發的 Apache CouchDB, 基於 Facebook Thrift 架構的 ThruDB, Ruby 開發的 StrokeDB, 或 Java 為基礎的 FeatherDB。這些資料庫具備分散式且容錯的設計,而且都適合塞 schema-free 的資料。唯一的問題是你還是得自己架設一堆伺服器,才是「正」分散式、容錯設計。

直到最近 Google App Engine (視訊說明) 推出正式的服務租用價格,由於費用極為便宜,我便開始認真考慮是否可以把資料庫移到網路公司所提供的 Platform-as-a-Service

Google App Engine 提供的是以 Python 語言為基礎網站應用軟體開發環境,其中提供 Datastore API,是基於 BigTable 上所開發,以提供了所謂 Scalable data-backed。另外一個價格與功能相仿便是 Amazon SimpleDB (但是 GAE 的硬碟儲存費用便宜多了)。這兩組服務所提供的都不是標準的 SQL 語法,而是特定的 API 搭配特製的查詢語法,Datastore 是 GQL, SimpleDB 則設計了自己的 query language.自然,網路上已經出現了根據此 document-oriented database 與 RDBMS 的交相論戰,如 Ryan Park 所寫的 Top 10 Reasons to Avoid the SimpleDB HypeYurii Rashkovskii (StrokeDB 的作者) 的回覆 Top 10 Reasons to Avoid Document Databases FUD

對我而言,我並不需要 RDBMS 的特色,key-value 的資料庫形式已經可以滿足我的要求。問題在於系統是否可以處理我的需求,根據 High Scalability Todd Hoff 的文章指出,GAE 的 Datastore API 似乎有些速度上的問題、以及 Application Quotas 的限制,如此還必須實際再深入研究軟體的設計方式。而 Amazon SimpleDB 尚處於 Limited Beta 的狀態,因此還不能進行實際的評估。此外,目前這些方法還無法做 Path queries,是下一個研究方向。