天天看點

面向 PHP 開發人員的 CouchDB 基礎知識

Thomas Myer , 負責人, Triple Dog Dare Media

面向 PHP 開發人員的 CouchDB 基礎知識

Thomas Myer 是一名顧問、作家和講師,居住在 Austin。他創立了 Triple Dog Dare Media 并在 Twitter 上以 @myerman 撰寫博文。

簡介:  作者 Thomas Myer 向資深 PHP 開發人員講述如何把 CouchDB 添加到他們的技術工具箱中。

如果您是位典型的 PHP 開發人員,就不難通過以往的項目得到這樣一個結論:在多數(如果不是全部)情況下,為了進行動态資料處理,您都會讓 PHP 與資料庫後端進行對話;而在這些執行個體中,99% 的情況下使用的都是 MySQL。

如今,使用關系型資料庫無可厚非。如果所處理的資料結構複雜,并具有多種關系,那麼這麼做是很合理的。您可以順利地(或是不太順利地,取決于您對 SQL 的熟悉程度)進行對模式、資料關系、表等等的處理。

不過,您所從事的項目有時也會讓您不經意間心生疑問:“為什麼我要做所有這些工作?” 您所從事的這個項目包含了一些簡單的或難以預測的資料 — 在不同的日子獲得的資料字段可能不同甚至事務之間的資料字段都不盡相同。若是建立一個模式來預測将會出現什麼資料字段,結果很可能會得到内含大量空字段的 表或大量的映射表。

常用縮略語

  • Ajax: 異步 JavaScript + XML
  • API: 應用程式程式設計接口
  • GUID: 全局惟一标示符
  • HTTP: 超文本标記語言
  • JSON: JavaScript 對象注釋
  • REST: 具象狀态傳輸
  • SQL: 結構化查詢語言
  • UUID: 通用惟一辨別符

對于這些項目,您需要采用一種不同的方式 — 不涉及關系型資料庫。在這些情況下,您需要的是一個基于文檔的、沒有模式的、具有扁平位址空間的特别資料庫。簡言之,您需要 Apache CouchDB。

什麼是 CouchDB?

CouchDB 是(根據 Apache CouchDB 網站):

  • 一個文檔資料庫伺服器,可通過 RESTful JSON API 通路。
  • 為特殊目的而設計,無模式,具有扁平位址空間。
  • 分布式的、特性豐富、具備雙向沖突檢測及管理的增量複制。
  • 可查詢、可索引、具有一個面向表的報表引擎,使用 JavaScript 作為引擎的查詢語言。

這意味着,您可以建立一個能夠接受 JSON 文檔的 CouchDB 資料庫。每個文檔均有一個惟一的修訂 ID 和自身結構,而且所有文檔均存儲于同一個扁平的集合内。例如,假設您設定了一個履歷集。第一個履歷具有的字段包括:名、姓、電話号碼、電子郵件位址、 Twitter 帳戶、特長以及詳細的工作經曆。而第二個履歷則隻有名、姓、電子郵件位址以及一個簡短的工作經曆。這種差異足以使關系型資料庫變得非常不适合,但對于 CouchDB,這點差異稀松平常。

簡言之,一個 CouchDB 文檔就是一個由多個命名字段組成的對象。這些字段的值可以是字元串、布爾值、數字、日期、順序清單或關聯映射。清單 1 展示了一個示例履歷文檔。

清單 1. 一個簡單的 CouchDB 文檔

{
"Firstname": "Tom"
"Lastname": "Myer"
"Twitter": "@myerman"
"Email": "[email protected]"
"Skills": ["php","couchdb","xml","json"]
"Work History": ....
}
                  

到目前為止,如果您習慣了使用 JSON,那麼不會覺得有太大出入。即便您不習慣,您仍然可以将此文檔對應成您所熟悉的東西,比如一個 PHP 數組。實際上,您可以将這些内置的 JSON encode/decode 函數用于 CouchDB,或者您也可以選擇一種更為面向對象的方式。

為了從一個集合查詢資訊,您可以通過 RESTful JSON API 使用各種便利的查詢方法。使用 JSON 簡化了很多問題。還有一點,作為一個熟悉 JavaScript、Ajax 和 JSON 的 Web 開發人員,您無需掌握 SQL 也能完成任務。

在繼續之前,最好暫停一下,先來着重強調幾點。CouchDB 不是一個關系型資料庫。這一點我可能早就說過了,但是它需要反複強調。不要試圖以關系型資料庫的方式使用 CouchDB,比如插入 ID 字段來幫助理清文檔間的關系。與建立關系不同,您需要将想要的内容塞入到文檔,然後繼續。

此外,CouchDB 亦不是一個面向對象的資料庫。它不是什麼本地對象、持久資料層供您用作面向對象結構的基礎。千萬不要這麼認為。

安裝 CouchDB

如果您使用的是 Mac OS X,CouchDB 的安裝過程十分簡單:

在 Linux 内安裝

您的 developerWorks 編輯能夠在他的 Ubuntu Linux 筆記本上以如下兩個步驟安裝 CouchDB:

sudo apt-get install couchDB
sudo /etc/init.d/couchdb start
      

此軟體已經處于存儲庫内并會自然加載。

  1. 打開一個 Terminal 視窗并鍵入

    sudo port install couchdb

  2. 在系統提示後,鍵入您的根密碼。
  3. 啟動 MacPorts 來安裝所需的 CouchDB 包。
  4. 從 Terminal 視窗,運作如下指令來檢索最後一分鐘所做的任何更改或依賴項:

    sudo port upgrade couchdb

  5. 要使 CouchDB 啟動起來并運作,在 Terminal 鍵入如下指令:
    sudo launchctl load -w /opt/local/Library/LaunchDaemons/org.apache.couchdb.plist
                                  
    這會啟動 CouchDB 伺服器并保持它持續運作,是以隻要重新開機 Mac,它就會随之啟動。

為了檢視 CouchDB 的實際效果,在您的浏覽器内鍵入 http://127.0.0.1:5984/_utils/index.html。Futon 實用工具就會出現,如圖 1 所示。

圖 1. Futon 實用工具

面向 PHP 開發人員的 CouchDB 基礎知識

在 Windows® 系統上,過程将會有些複雜,因為您将需要先安裝 Microsoft® C 編譯器 Cygwin、其他的一些前提條件(比如 cURL、ICU 和 SeaMonkey)、下載下傳并安裝 Erlang 和 Couch 源代碼、根據 README 檔案對其進行配置,然後才能進行一次完整的安裝。這一過程在 CouchDB wiki(參見 參考資料 )内有詳細的描述。您還将能夠找到針對 Linux®、Berkeley Software Distribution (BSD) 和其他環境的指導。

使用 CouchDB API

在進入 PHP 之前,最好是先對 CouchDB API 有些了解,此 API 可通過 HTTP

GET

PUT

請求通路并傳回 JSON 格式的資料。不管您使用的是何種語言 — PHP、Microsoft Active Server Pages (ASP)、Ruby、Python 或更為簡單的 jQuery Ajax 函數,這種設定都會使從 Web 應用程式存儲和檢索資料得到簡化。

本節展示如何使用這個 cURL 指令行工具向 CouchDB 發出

GET

POST

PUT

DELETE

請求。掌握了這個 API 之後,就可以借助一個特别的 PHP 包裝器簡化開發任務。

您首先需要運作的(仍然是從 Terminal 視窗)是這個指令:

curl http://127.0.0.1:5984/

。随後,應該會得到類似于

{"couchdb":"Welcome","version":"0.10.0"}

的一個響應。這隻是為了告訴您 CouchDB 已經啟動并運作以及所使用的是何版本。如果您沒有看到這個消息,那麼就請重新進行安裝和配置直至 CouchDB 啟動并運作。

現在,嘗試列出在 CouchDB 内設定的所有集合。運作

curl -X GET http://127.0.0.1:5984/_all_dbs

如果 CouchDB 是初次安裝,應該會看到響應

[]

,這意味着沒有任何集合或資料庫(方括号代表的是一個空的 JavaScript 數組)。請注意在這個 cURL 指令中,使用了

-X

選項來顯式指定一個

GET

操作。

現在,讓我們通過建立一個資料庫來解決該問題:

curl -X PUT http://127.0.0.1:5984/songs
                  

在運作上述指令後,會得到響應

{"ok":true}

。現在您知道您可以檢視

ok

屬性來确認成功與否。再次運作

curl -X GET http://127.0.0.1:5984/_all_dbs

,結果會得到一個非空數組:

["songs"]

。并且,您的 CouchDB 執行個體内具有這樣一個資料庫:songs 。

現在嘗試建立另一個名為 songs 的資料庫。如果您再次運作

curl -X PUT http://127.0.0.1:5984/songs

,将會獲得一個如下所示的錯誤消息:

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

是以您可以很容易地檢視

error

屬性來确認問題發生與否。

建立第二個名為 foobar 的資料庫:

curl -X PUT http://127.0.0.1:5984/foobar
                  

如果運作

curl -X GET http://127.0.0.1:5984/_all_dbs

,結果會獲得響應

["songs","foobar"]

。為了去掉第二個資料庫,可以向它傳遞一個

DELETE

調用:

curl -X DELETE http://127.0.0.1:5984/foobar
                  

運作

curl -X GET http://127.0.0.1:5984/_all_dbs

表示您已經回至

["songs"]

現在繼續,在 songs 資料庫内建立一些文檔。毋庸置疑,您想要在這個資料庫記憶體儲一些歌曲,這些歌曲具有曲名、藝人名稱和專輯名稱字段。要建立一個文檔,遵循如下這個模式:

curl -X PUT http://127.0.0.1:5984/songs/*id* -d '{ *json_data* }'
                  

注意到先是調用資料庫的名稱,随後是 ID(要求 ID 不僅要在這個 CouchDB 執行個體中惟一,而且還要盡量在所有執行個體中惟一),再後來是 JSON 資料。

如何獲得惟一 ID?可以使用一個 UUID(或一個 GUID)作為惟一 ID,或者也可以建立某種綜合了各種小塊資料的自然鍵(比如,歌曲名中用下劃線代替空格,再加上時間戳),或者是讓 CouchDB 為您建立一個惟一 ID (這個過程很慢)。上述方式都不錯,隻是不要像在 MySQL 環境内那樣使用自動增量的值。

現在,向您的資料庫内輸入一首歌曲:

curl -X PUT http://localhost:5984/songs/whatever_you_like -d /
	'{"title":"Whatever You Like", "artist":"T.I.","album":"Paper Trail"}'

{"ok":true,"id":"whatever_you_like","rev":"1-1d915e4c209a2e47e5cf05594f9f951b"}
                  

請注意我對這個惟一 ID 采用了一個十分簡單的方式(使用了一個簡化了的歌曲名稱,用下劃線代替了空格)。這種簡單的方式對于目前的需要還能滿足。幸運的是,在 PHP 内将要使用的包裝器會幫助您建立更好的 ID。也請注意我立即收到了一個 “ok” 響應,并且其中的文檔 ID 和

rev

屬性還告知了所設定的修訂版本。

要檢視剛剛添加的這個文檔,可以嘗試:

curl -X GET http://localhost:5984/songs/whatever_you_like

{"_id":"whatever_you_like","_rev":"1-1d915e4c209a2e47e5cf05594f9f951b", 
	"title":"Whatever You Like", "artist":"T.I.", "album":"Paper Trail"}
                  

如果您一直在 Futon 内嘗試,應該能夠單擊這個歌曲資料庫名并在文檔清單内看到一個

whatever_you_like

項。單擊該連結會顯示所感興趣的這個文檔的詳細資訊,如圖 2 所示。

圖 2. 文檔詳細資訊

面向 PHP 開發人員的 CouchDB 基礎知識

您逐漸發覺 — 用 JSON 做出 RESTful 請求後就會有事情發生。

現在,所有這些看上去都很好,但是如果您是一名 PHP 開發人員,可能會疑惑如何将這些綜合在一起形成自己熟悉的東西呢。下一節會向您介紹面向 CouchDB 的 PHP 包裝器。

使用 PHP

對于下一個步驟,您需要從 Github 下載下傳 PHP-on-Couch(參見 參考資料 )。 将解壓縮了的 /lib 檔案夾内容放入您的開發區域。在設定好工作區域後,建立一個簡單的 PHP 應用程式來與已經設定好的這個 CouchDB 資料庫(您的歌曲集)對話。建立一個新檔案,然後将其命名為 index.php。并在其内放入清單 2 内的代碼。

清單 2. CouchDB 連接配接設定

<?php
$couch_dsn = "http://localhost:5984/";
$couch_db = "songs";

require_once "./lib/couch.php";
require_once "./lib/couchClient.php";
require_once "./lib/couchDocument.php";


$client = new couchClient($couch_dsn,$couch_db);
?>
                  

上述代碼充當的是到 CouchDB 的連接配接代碼并且包含使用此資料庫所需的所有相關類。接着列出與資料庫相關的全部資訊,如清單 3 所示。

清單 3. 獲得資料庫資訊

try {
	$info = $client->getDatabaseInfos();
} catch (Exception $e) {
	echo "Error:".$e->getMessage()." (errcode=".$e->getCode().")/n";
	exit(1);
}
print_r($info);
                  

得到的結果應該類似于清單 4。

清單 4. 資料庫資訊

stdClass Object 
( 
	[db_name] => songs 
	[doc_count] => 2 
	[doc_del_count] => 0 
	[update_seq] => 2 
	[purge_seq] => 0 
	[compact_running] => 
	[disk_size] => 8281 
	[instance_start_time] => 1266082749089965 
	[disk_format_version] => 4 
)
                  

接下來,從歌曲資料庫中檢索一個文檔。清單 5 給出了所需代碼。

清單 5. 從資料庫中檢索一首歌

try {
	$doc = $client->getDoc('whatever_you_like');
} catch (Exception $e) {
	if ( $e->code() == 404 ) {
		echo "Document not found/n";
	} else {
		echo "Error: ".$e->getMessage()." (errcode=".$e->getCode().")/n";
	}
	exit(1);
}
print_r($doc);
                  

清單 6 給出了響應。

清單 6. 檢索到的歌曲

stdClass Object
(
    [_id] => whatever_you_like
    [_rev] => 1-1d915e4c209a2e47e5cf05594f9f951b
    [title] => Whatever You Like
    [artist] => T.I.
    [album] => Paper Trail
)
                  

很不錯,但是如何對一個文檔進行更新呢?可以做的更新有兩種:更改現有字段值;添加新字段和新值。對于後者,可以使用箭頭表示法(比如

$doc->new_field

),然後通過

storeDoc()

儲存更改。清單 7 顯示了更新一個文檔所需的代碼。

清單 7. 更新一個文檔

$doc->genre = 'hip-hop';
$doc->year = 2008;
try {
        $response = $client->storeDoc($doc);
} catch (Exception $e) {
        echo "Error: ".$e->getMessage()." (errcode=".$e->getCode().")/n";
        exit(1);
}
                  

運作此代碼,然後就可以檢索這個文檔 ID 并獲得清單 8 内所示的結果。

清單 8. 更新後的文檔

stdClass Object
(
    [_id] => whatever_you_like
    [_rev] => 2-12513a362693b300928aa45f82faed83
    [title] => Whatever You Like
    [artist] => T.I.
    [album] => Paper Trail
    [genre] => hip-hop
    [year] => 2008
)
                  

注意到

_rev

屬性已經從之前的

1-whatever

增加為

2-whatever

。借此,就可以很容易地判斷已經發生了更改。

那麼,該如何在資料庫記憶體儲一個新文檔呢?您可以執行個體化一個新對象并使用箭頭表示法來填充文檔内的字段。清單 9 顯示了所需代碼。

清單 9. 建立一個新文檔

$song = new stdClass();
$song->_id = "in_the_meantime";
$song->title = "In the Meantime";
$song->album = "Resident Alien";
$song->artist = "Space Hog";
$song->genre = "Alternative";
$song->year = 1995;

try {
	$response = $client->storeDoc($song);
} catch (Exception $e) {
	echo "Error: ".$e->getMessage()." (errcode=".$e->getCode().")/n";
	exit(1);
}
print_r($response);
                  

結果應該類似清單 10。

清單 10. 建立一個新文檔的結果

stdClass Object
(
    [ok] => 1
    [id] => in_the_meantime
    [rev] => 1-d65b03a9fe2f3c8095b08883e7cd97df
)
                  

結束語

至此,您應該具備了開始使用 CouchDB 和 PHP 的足夠資訊。您也應該能夠輕松建立您的基本更新表單并能在日後建立或更新資料庫内的現有文檔。PHP-on-Couch 包還為您提供了建立和删除資料庫以及使用 CouchDB 視圖等的其他方法。總之,本文有足夠資訊可以讓您從開始就有一個很好的起點。

參考資料

學習

  • 通路 CouchDB 項目站點。
  • CouchDB: The Definitive Guide 是 CouchDB 權威指南的一個免費線上版本。
  • 查閱 CouchDB wiki 尋找有關 CouchDB 疑問的答案。
  • 閱讀 Installing CouchDB on Windows 獲得在 Windows 平台上安裝資料庫的指導。
  • 通路 Installing CouchDB on Linux/BSD 獲得在運作 Linux 或 BSD 的計算機上安裝資料庫的指導。
  • 參閱 The CouchDB API Reference 了解本文使用的這個 API 的更多資訊。
  • 閱讀 “探索 CouchDB ” 了解 CouchDB 緣何如此突出。
  • PHP.net 是面向 PHP 開發人員的中心資源。
  • 查閱 “推薦 PHP 讀物清單 ”
  • 浏覽 developerWorks 上的所有 PHP 内容 。
  • 用 IBM developerWorks 的 PHP 項目資源 提高您的 PHP 技巧。
  • 要收聽針對軟體開發人員的有趣訪談和讨論,請通路 developerWorks podcasts 。
  • 要将資料庫與 PHP 結合使用?檢視 Zend Core for IBM ,它是一個無縫的、可以立即使用、易于安裝、支援 IBM DB2 V9 的 PHP 開發和生産環境。
  • My developerWorks 涵蓋了大量主題,是一個成功社群的典範。
  • 随時關注 developerWorks 技術活動 和網絡廣播 。
  • 查閱最近将在全球舉辦的面向 IBM 開放源碼開發人員的研讨會、交易展覽、網絡廣播和其他 活動 。
  • 通路 developerWorks Open source 專區 獲得豐富的 how-to 資訊、工具和項目更新以及最受歡迎的文章和教程 ,幫助您用開放源碼技術進行開發,并将它們與 IBM 産品結合使用。
  • 檢視免費的 developerWorks 示範中心 觀看并了解 IBM 及開源技術和産品功能。

獲得産品和技術

  • 從 Github 下載下傳 PHP-on-Couch 庫。
  • 使用 IBM 産品評估試用版軟體 改進您的下一個開發項目,這些軟體可以通過下載下傳獲得。
  • 下載下傳 IBM 産品評估試用版軟體 或 IBM SOA Sandbox for People 并開始使用來自 DB2®、Lotus®、Rational®、Tivoli® 和 WebSphere® 的應用程式開發工具和中間件産品。

文章來源:http://www.ibm.com/developerworks/cn/opensource/os-php-couchdb/index.html