PEAR MDB 數據庫抽象層 —— 一次編寫—隨處運行
發表時間:2023-08-19 來源:明輝站整理相關軟件相關文章人氣:
[摘要]Write once - run anywhere一次編寫——隨處運行這是Java的一句行銷口號,但是它同時也是PHP的關鍵特性之一。許多商業模型依賴于操作系統無關性來保證產品能夠銷售給廣泛的客戶群...
Write once - run anywhere
一次編寫——隨處運行
這是Java的一句行銷口號,但是它同時也是PHP的關鍵特性之一。許多商業模型依賴于操作系統無關性來保證產品能夠銷售給廣泛的客戶群體。因而,為什么要把你自己綁在某種數據庫廠商的身上呢?數據庫抽象層使得你能夠與數據庫獨立的開發你的應用程序。但是,通常情況下它們對性能的影響超過了你所希望的,要么他們并不足夠抽象以消除所有和特定數據庫相關的代碼。
這篇文章將教給我什么?
這篇文章將對數據庫抽象包 PEAR MDB 有一個很好的介紹。文章的焦點將是對 MDB 超越類似包所提供的更先進的特性,例如數據類型抽象和基于 XML 的 schema 管理。對 PHP 和 SQL 的基本理解是推薦的。
為什么另外再要一個數據庫類?
通常, web 工程在客戶已經確定了要使用那種 RDBMS (關系型數據庫管理系統)之后被添加給已經存在的 IT 基礎結構。即使那并不是因為不同的預算可能影響的你選擇何種數據用于部署的情況。最終,你作為開發者可能簡單的偏好于不把自己綁在某個廠商身上。自此,意味著給每個支持的數據保持版本或者犧牲更多性能但是獲得多于必須的易用性:走入 PEAR MDB 吧。
MDB 是著眼于使得編寫 RDBMS 無關的 PHP 程序成為簡單的過程的數據庫抽象層。大部分其他的 PHP 的所謂數據庫抽象層緊緊給所有支持的數據庫提供了一個公用 API 以及非常有限的抽象(大部分只是針對序列的)。MDB 另一方面能夠用來抽象所有數據庫發送和接收的數據。甚至數據庫 schema 都能被定義為 RDBMS 無關的格式。但是它提供這些功能的同時仍然保持了很高的性能以及簡單易用。這是通過深入觀察兩個流行的數據庫抽象層,PEAR DB 和 Metabase, 之后并且對它們進行了融合后獲得的。而且在融合過程中,趁著這個機會清理了它們融合后的 API 以及任何影響性能的設計。
MDB 是怎樣出現的?
早在 2001 年的秋天,我就在尋找一種可能能夠讓我公司的程序框架與 RDBMS 獨立的數據庫抽象包。這個目標是把特定數據庫相關的代碼數量減少到零。我發現提供這樣的功能的唯一的一個包是 Metabase。但是 Metabase有一些部分是因為為了和 PHP3 兼容的讓人不舒服的 API。盡管如此,我們決定 Metabase 是我們唯一的選擇。但是即使是在給 Metabase 增加了一個性能改進的補丁之后,我們仍然感到我們放棄了太多的性能。我們在 2001 年的 PHP 國際會議上碰到了 Metabase 的作者,并且我們談論了讓像 Metabase 這樣的東西成為 PEAR 工程一部分的好處。后來不久,在 PEAR 郵件列表上就 PEAR DB 和 Metabase 融合的可能的好處又開始了一場討論。在我們公司進行了許多討論之后,我們決定承擔這個任務。數個月的艱辛工作之后,我們現在有了 MDB 的第一個穩定的 release。
MDB 給你提供了什么?
MDB 結合了 PEAR DB 和 Metabase 的大部分特性。實際上,PEAR DB 的特性中唯一不再存在的是作為結果集返回一個對象。我們放棄了這個特性是因為這個特性不常用而且對于性能的損失是非常明顯的。許多開發上的時間用在了使得 API 盡可能的好用。最終,MDB 非常高地提供了這些功能至少和 PEAR DB 一樣快而且比 Metabase 快很多。這些最重要地特性的列表:
OO 風格的 API
預準備的查詢模擬
給所有傳遞進來以及從數據庫中取出的數據的完全的數據類型抽象(包括 LOB 支持)
事務支持
數據庫/表/索引/序列創建/拋棄/改變
RDBMS 無關的數據庫 schema 管理
繼承進 PEAR 框架(PEAR 安裝程序,PEAR 錯誤處理等)
那么它如何使用呢?
MDB 提供了一些非常先進的抽象特性。記住這些特性只是供選擇的是很重要的。但是在編寫 RDBMS 無關的 PHP 程序時使用它們是非常重要的。一個展示使用 MDB 是多么簡單的例子在文章的結尾的 "鏈接和文獻" 部分。如前面所說,文章的焦點是介紹使得 MDB 與其他 PHP 數據庫抽象層不同的那些特性。你可以在隨本期文章一同包裝的 CD 中找到所有這些例子腳本的代碼。
但是,首先我們需要把 MDB 安裝上去。使用 PEAR 安裝程序這其實非常容易。我不能在這篇文章中完整的講述 PEAR 安裝程序但是我聽說下一期將非常詳細的討論 PEAR 框架的里里外外。讓安裝程序運行于 Windows 的工作在進行當作但是支持仍然有一點古怪。對于 *nix 系統你需要 PHP 的 CGI 版本安裝在了你的系統并且簡單地運行下面地命令:
lynx -source go-pear.org php
在安裝完成之后你只需要再輸入一行命令那么就全部搞定了。
pear install MDB
如果前面的過程對你來說不管用,總是有從 PEAR MDB 主頁中直接獲得包的選項。URL 列于文章的最后。
利用數據類型抽象
因為大部分數據庫傾向于有一些個性或者怪癖,對于MDB來說把這些不同之處給開發者隱藏起來非常重要。MDB 通過定義自己的內部數據類型來達到這點:text,boolean,integer,decimal,float,date,time,time stamp,large objects(文件)。所有傳遞給數據庫和從數據庫獲取的數據都能轉換成 MDB 的內部格式或者從數據庫的內部格式轉化回來。本節相關的例子腳本能夠再 datatype 目錄中找到。讓我們看看下面的查詢:
$session = '098f6bcd4621d373cade4e832627b4f6';
// set time out to 30 minutes
$timeout = time()+60*30;
// SELECT query showing how the datatype conversion works
$query = 'SELECT createtime, user_id FROM sessions';
$query .= ' WHERE session = '.$session;
$query .= ' AND lastaccess < '.$timeout;
這個查詢如果發送給數據庫的話八成要失敗。原因是存儲在 $name 中的值需要轉換為正確的字符串格式。這也許意味著 $name 的內容可能有特殊的轉義字符或者被引號包圍。PEAR DB 為此提供了方法 DB:.quote()。在 MDB 中這個方法叫 MDB::getTextValue()。不同之處是 MDB 給每種前面所列的數據類型都提供了這樣的函數。因而我們也能夠把 $timeout 轉換為正確的格式。
// convert $timeout to the MDB timestamp format
$timeout = MDB_date::unix2Mdbstamp($timeout);
// SELECT query showing how the datatype conversion works
$query = 'SELECT createtime, user_id FROM sessions';
$query .= ' WHERE session = '.$mdb->getTextValue($session);
$query .= ' AND lastaccess < '.$mdb->getTimestampValue($timeout);
為了作個演示,讓我們假定我僅僅想要獲取第一行。MDB::queryRow() 獲得第一行,它釋放結果集并且返回其內容,因而它正是我們所要的。
$result = $mdb->queryRow($query);
但是不同的 RDBMS 返回像日期這樣的數據時用的格式是不同的。因此,如果我們然后要對一些數據進行計算,不管選擇的 RDBMS 是什么,把數據以相同的格式返回是重要的。這個可以由 MDB 半自動地完成。你所有需要做的是告訴你的結果列將是什么樣的類型,MDB將處理轉換的工作。最簡單的辦法是把這樣的信息傳遞給查詢函數。
$types = array('timestamp', 'integer');
$result = $mdb->queryRow($query, $types);
這告訴 MDB 結果集的第一列類型是 'timestamp' 以及第二列是'integer'。所有查詢函數能夠接受這樣的元信息作為可選的參數。數據還能事后用 MDB::setResultTypes() 來設置。取決于數據獲取于的數據庫,它然后將被相應的轉換返回的數據。MDB 內部的 timestamps 的數據格式是遵循 ISO 8601 標準的。其他像 PEAR::Date 這樣的包能夠處理這種格式。MDB 還在 MDB_Date 類中提供了一些數據格式轉換函數,它們能夠被可選的包含。
因為相當多的 RDBMS 以相同的方法返回整數數據,沒有必要轉換整數數據。因而,為了獲得稍許的性能改進你能夠這么做:
$types = array('timestamp');
$result = $mdb->queryRow($query, $types);
這樣只有結果集的第一列會被轉換。當然,如果 MDB 用于返回整數不同的數據庫,這可能成為一個問題。然而,稍許的性能改善可能并不值得冒這個風險。但是再一次的,它顯示了這些特性的使用僅僅是供選擇的。
Listing 1 展示了一個使用預準備的查詢的例子。如果你必須運行大量查詢而唯一的差別是數據傳遞給數據庫,但是查詢的結構還是一樣的,這些能夠相當的方便。高級的數據庫能夠在內存中儲存解析好的查詢來加速性能。
Listing 1
$alldata = array(
array(1, 'one', 'un'),
array(2, 'two', 'deux'),
array(3, 'three', 'trois'),
array(4, 'four', 'quatre')
);
$p_query = $mdb->prepareQuery('INSERT INTO numbers VALUES (?,?,?)');
$param_types = array('integer', 'text', 'text');
foreach ($alldata as $row) {
$mdb->execute($p_query, NULL, $row, $param_types);
}
在 $alldata 中儲存的所有四個數組將用于 execute 語句。數據將自動被轉換為正確的格式。因為這是一個插入語句,MDB::execute() 的第二個參數被設置為 NULL 因為我們將沒有任何結果列需要我們設置數據類型。
在支持的數據類型中還有 LOB (大對象),它使得我們能夠在數據庫中儲存文件。二進制文件儲存在 BLOB (二進制大對象)中而且普通文本文件儲存在 CLOB (字符大對象)中。在 MDB 中你僅僅能夠使用預準備的 INSERT 和 UPDATE 查詢儲存 LOB。使用 MDBA::setParamBlob() 或者 MDB::setParamClob() 你能夠設置預準備查詢的 LOB 域的值。兩個函數都預期傳遞一個 LOB 對象,而它能夠使用 MDB::createLob() 創建。
$binary_lob = array(
'Type' => 'inputfile',
'FileName' => './myfile.gif'
);
$blob = $mdb->createLob($binary_lob);
$character_lob = array(
'Type' => 'data',
'Data' => 'this would be a very long string container the CLOB data'
);
$clob = $mdb->createLob($character_lob);
如你能看到的,MDB::createLob() 被傳遞一個關系數組。Type 鍵的值可能是以下中的一個:data, inputfile 或者 outputfile。前兩個用于你想要把 LOB 寫入數據庫的時候。如果你有一個儲存在變量中的 LOB,你應當在 需要使用 inputfile 時從文件直接讀取 LOB。最后,outpufile 應當在你想要從數據庫中讀取 LOB 時使用。取決于你是否使用數據或者 inputfile 你需要給 Filename 鍵或者 Data 鍵指定一個值,像上面的例子那樣,F在,我們將把前面的 LOB 儲存到數據庫中去。
$p_query = $mdb->prepareQuery('INSERT INTO files (id, b_data, c_data) VALUES (1, ?, ?)');
$mdb->setParamBlob($p_query, 1 , $blob, 'b_data');
$mdb->setParamClob($p_query, 2 , $clob, 'c_data');
$result = $mdb->executeQuery($p_query);
為了從數據庫中獲取上面的文件,我們需要首先從數據庫中選擇數據并且使用 MDB::createLob() 創建 LOB 對象。這次我們將設置 'Type' 為 'outputfile'
$mdb->query('SELECT b_data FROM files WHERE id = 1');
$binary_lob = array(
'Type' => 'outputfile',
'Result' => $result,
'Row' => 0,
'Field' => 'b_data',
'Binary' => 1,
'FileName' => './myfile2.gif'
);
$blob = $mdb->createLob($binary_lob);
現在我們能夠使用 MDB::readLob() 從結果集中讀取 LOB。傳遞長度 0 給 MDB::readLob() 意味著整個 LOB 被讀取和儲存在我們前面指定的文件中。一旦任務完成了,我們可以把資源釋放了。你也可以設置任何大于零的長度并且使用一個 while 循環檢查 MDB::endofLob() 來讀取 LOB。
$mdb->readLob($blob, $data, 0);
注意你不要把這個獲取函數和 bulk 獲取函數像 MDB::fetchAll()搞混了,因為這將在大部分 PHP 數據庫擴展中導致問題。在一些時候,MDB 可能能夠使用 bulk 獲取函數獲得 LOB。
如我們在這節所見,MDB 特性本身的原生數據類型集自動映射于數據庫中的原生數據類型。這保證了無論我們發送和從數據庫接收什么樣的數據,它都能與使用的 RDBMS 無關的使用相同的格式。如我在本節開篇已經提到的,這明顯需要數據庫使用的數據類型是 MDB 預期的。這種需要被用于確保映射所耗費的代價很小。下一節將教給我們 MDB 如何輔助在數據庫中使用正確的數據類型。
使用 XML schema 文件
利用在上個段落中描述的特性,你能編寫真正的數據庫獨立的程序。但是 MDB 嘗試向前更加邁出一步:它允許你用 XML 定義你的 schema。一個管理器把這種 schema 轉換為給每種 RDBMS 的必要的 SQL 語句。這意味著你能對所有支持的 RDBMS 使用相同的 schema。本節的例子能夠在 xml_schema 目錄中找到。
我們現在將從頭編寫一個 XML schema 文件。首先,我們必須定義一個 XML 文檔。數據庫定義是包含在一個 database 標簽之中的。數據庫的名字是使用 name 標簽定義的。create 標簽告訴管理器數據庫是否需要在它不存在的時候被創建。如果你把你的 schema 文件分割成好幾個文件你你首先提交給管理器的那個文件中把 create 設置為 1。
<?xml version="1.0" encoding="ISO-8859-1" ?>
<database>
<name>auth</name>
<create>1</create>
</database>
可能你已經從數據庫名 auth 猜出了這個數據庫的目的是用于儲存簡單的驗證程序的用戶數據。Listing 2 定義了在其中我們能儲存用戶數據的表。
Listing 2
<table>
<name>users</name>
<declaration>
<field>
<name>user_id</name>
<type>integer</type>
<notnull>1</notnull>
<unsigned>1</unsigned>
<default>0</default>
</field>
<field>
<name>handle</name>
<type>text</type>
<length>20</length>
<notnull>1</notnull>
<default></default>
</field>
<field>
<name>is_active</name>
<type>boolean</type>
<notnull>1</notnull>
<default>N</default>
</field>
</declaration>
如你能看到的,如使用 XML 時可以預期的,東西變得有一些冗長。不用擔心:我們有一個基于瀏覽器的工具稱為 MDB_frontend 使得這個過程更加簡單。我將在這篇文章的后面談論這個工程。可能這極其詳細地表格描述的優點是非常明顯。前面例子中的表格被稱為 users 并且我們定義了 3 個域:類型為整數的 user_id,類型為文本的 handle 和類型為邏輯型的 is_active。記住如果你如前一節那樣傳遞了必要的元數據 MDB 為你處理類型抽象。你還不需要 MDB 把這些類型映射為你的 RDBMS 中的什么。在每個域聲明中還能使用的其他標簽是可選的:length,notnull,unsigned 和 default。
下一件我們現在需要做的事情是通過在 user_id 域放置恰當的索引確保 user_id 是唯一的。索引定義就在聲明標簽之內(Listing 3)。
Listing 3:
<table>
<name>users</name>
<declaration>
<index>
<unique>1</unique>
<name>user_id_index</name>
<field>
<name>user_id</name>
<sorting>ascending</sorting>
</field>
</index>
</declaration>
在 listing 3 中的定義在域 user_id 中創建一個唯一的上升排序的名為 user_id_index 的索引。當然,我們可以簡單地添加另外一個域標簽在索引定義中指定多于一個的域。我們現在仍然沒有提到的是為我們產生唯一的用戶 id 的序列。
<sequence>
<name>users_user_id</name>
<start>1</start>
<on>
<table>users
<field>user_id</field>
</on>
</sequence>
上一個例子非常的繞彎。一行行看過來,我們看到首先打開一個 sequence 標簽,跟著一個指定序列名字的 name 標簽。這之后跟著一個定義序列初始值的 start 標簽。現在,我們打開一個可選的 on標簽。這兒我們需要設置一個表中的指定域。這個信息是管理器用來把序列的值設置為 users 表的 user_id 域的最大值。如果 users 表是空的,作為替代使用的是 start 標簽中指定的值。請注意在 start 標簽中指定的值是我們調用 MDB::nextId() 返回的第一個值。
當然,你也能使用任何值初始化表。例如你可能想要用你總是想要包含在你的程序中的管理用戶來初始化前面的表格。為了這么做,我們需要把一個 initialization 標簽添加給 table 標簽。Listing 4 定義了一在另外一用 insert 標簽包括的行之后的行。
Listing 4
<table>
<name>users</name>
<initialization>
<insert>
<field>
<name>user_id</name>
<value>1</value>
</field>
<field>
<name>handle</name>
<value>default</value>
</field>
<field>
<name>is_active</name>
<value>Y</value>
</field>
</insert>
</initialization>
如你從上個例子中能看到的那樣,所有我們需要做的就是給表的每個域設定值。我們現在已經知道了必要的基礎知識來創建一個 MDB 的 XML schema。下一步是把這個 schema 文件傳遞給 MDB 管理器。
$manager = new MDB_Manager;
$input_file = 'auth.schema';
// we do not have to connect to a specify a specific database at this time
$dsn = "mysql://$user:$pass@$host";
$manager->connect($dsn);
$manager->updateDatabase($input_file, $input_file. '.before');
我們現在有了一個新的名字叫 auth 的數據庫,它有一個表叫 users。在域 user_id 有一個索引。而且在表中還有一行。我們還有一個序列稱為 users_user_id,它將被初始化為 1。因此序列中的下一個值就是 2。最后,schema 的一個拷貝以名字auth.schema.before 被創建。這是因為我們給 MDB_Manger::updateDatabase() 傳遞了可選的第二個參數。在下一節我們將看到為什么要創建這個拷貝。
所有這些都非常令人驚奇但是它變得更好。許多情況下程序需要在某些地方作出改變。例如我們可能決定需要把表的名字從 users 變成 people。我們可能還需要增加一個域 pwd 來儲存密碼域(請檢查 textbox 的保留字)。
保留字
我們沒有稱那個域為 password 的原因是那是 Interbase 中一個域名的保留字。因為我們需要 RDBMS 獨立,MDB 管理器要么給出一個警告要么在 fail_on_invalid_names 選項被設置為真的時候(這是缺省值)失敗。
在過去的時候,你可能現在正處于把你所有已經有的東西變成這種新的 schema 的痛苦之中。但是由于 MDB 這些工作能夠自動完成。在 listing 5 中是我們對我們的表格定義進行的修改:
Listing 5
<table>
<name>people</name>
<was>users</was>
<declaration>
<field>
<name>pwd</name>
<type>text</type>
<length>32</length>
<notnull>1</notnull>
<default></default>
</field>
</declaration>
現在我們想要管理器來作出必要的改變,但是在此之前我像提一下可能的陷阱。因為我們把表從 users 更名為 people,我們還需要把所有對原來名字的引用進行更改,比如我們建立的序列。在 on 標簽中的索引需要更改為指向 people 表。為了達到這個目的,我們把 shcema 的新舊版本傳遞給管理器。這酒是為什么我們在第一次調用 MDB_Manager::updateDatabase() 時我們創建一個 .before 文件的原因。這確保了我們有一個舊版本的 shcema 來與新的版本進行比照。
$input_file = 'auth.schema';
$manager->updateDatabase($input_file, $input_file.'.before');
所有的就是這樣!users 表現在稱為 people 并且我們也有了一個 pwd 域。
我現在要看看 XML schema 格式的最后一個特性。如果你想要編程性的使用管理器,這個特性尤其重要。假設你有好幾個有相同驗證程序運行在你的數據庫服務器的客戶。 每個客戶有一個服務器運行在這個服務器有相同的 schema 只有微小的區別:數據庫的名字。可能為每個客戶單獨保存 schema 文件是可行的因為更新周期可能不是一樣的,這不是我們例子驗證程序的情況。這兒所有的客戶同時更新。XML schema 文件允許我們為此可以使用變量。
<?xml version="1.0" encoding="ISO-8859-1" ?>
<database>
<name><variable>name</variable></name>
</database>
我們現在在運行時設置變量為任意我們需要的東西。
foreach($clients as $name) {
$variables = array('name' => $name)
$manager->updateDatabase($input_file, $input_file.'.before', $variables);
}
XML schema 管理是 MDB 提供的數據庫抽象概念的另外一個非常重要的部分。它使得我們保持我們的 schema 定義與特定的 RDBMS 無關。但是使用這個格式還確保了使用正確的原生數據類型因而 MDB 能夠正確地映射它的原生數據類型。最后,因為數據是基于 XML 的,編寫產生或者讀取 XML schema 文件的工具要容易一些。
聽起來不錯但是我的應用程序已經使用了……
大部分讀者可能發現它們處于這樣的境地——他們已經有了大量運行于其他數據庫抽象層的程序。由于 MDB 的出身,大部分 PEAR DB 的用戶應當發現 MDB 感覺上非常類似,因為 MDB 的 API 是基于 PEAR DB 的。Metabase 用戶應當發現他們所有偏愛的功能都在 MDB 中有對應的東西。XML schema 格式和 Metabase 中的是一摸一樣的。一個完全的指導來引導你把已經寫好的程序移植到 MDB 中超出了本文的范圍,但是我將利用這個機會給一些提示。如果你有任何具體的問題,放心的發信來詢問我。
為了把你的 PEAR DB 程序移植到 MDB,最好的起點是 PEAR wrapper。你能使用 PEAR wrapper 來運行你的程序。wrapper 當然增加了一些額外負擔,因而你可能有些想要移植到原生的接口。那么第一步是列出所有你程序當前使用的 PEAR DB 函數。然后看看 wrapper 從中找出任何 API 上的區別。有兩個你要注意的關鍵區別:結果集不再是對象而且所有的允許你傳遞結果集的數據類型的查詢方法將導致參數順序上的少許改變。第一個區別意味著不能再結果對象上調用獲取函數。
$result = $db->query($sql);
$row = $result->fetchRow();
你現在必須調用 MDB 對象來進行獲取:
$result = $mdb->query($sql);
$row = $mdb->fetchRow($result);
第二個區別通過觀察 wrapper 可以輕易的被解決。如你再 wrapper 中能看到的,你可以再 MDB 期望得到結果集的數據類型的地方簡單地傳遞 NULL,F在,你地程序應當能夠使用 MDB。當然,你現在沒有真正得到了 MDB 地高級特性優點的益處。這最有可能的是需要對你當前的數據庫 schema 進行一些改動。管理器能夠嘗試反向地從已經存在的數據庫中獲取 XML schema 文件。一個非常簡單的前端可以在 MDB 包中找到:reverse_engineer_xml_schema.php 腳本。極有可能你將需要手動修正產生的 XML schema 恩見,但是它將給你一個很好的開始。
如果你想要把你已經存在的程序從 Metabase 移植到 MDB 你將必須改動所有的函數調用。查看 Metabase wrapper 需要改動什么將變得非常明顯。如果你知道正則表達式你可能能夠完成大部分這樣的替換工作。無論如何,你應當向前并且運行你原來喜愛的高級抽象特性但是現在用的是 MDB。你可能注意得到的是函數名變得更加簡短了。如果你作一些性能測試,你也將看到可觀的性能改善。
那么 MDB 將來會是什么樣子呢?
本文發表時 MDB 可能已經不再是原來的 1.0 release 了。在原來的 MySQL 和 PostGreSQL 驅動之后,MDB還將有一個 ODBC 驅動以及可能的更多的驅動。這是 MDB 開發過程中關注的關鍵區域之一。一旦 MDB 在驅動方面跟上了 PEAR DB,它很有可能成為 PEAR 框架中標準的數據庫抽象層。
但是還有另外一個開發中的關鍵領域:MDB_frontend 工程。MDB_frontend將成為基于 MDB 和 MDB 管理器的 phpMyadmin。有了這個工具,你將能夠瀏覽儲存在 MDB 支持的 RDBMS 中的數據庫。MDB_frontend 將同時顯示原生和 MDB 數據類型。模擬的特性比如 MySQL 中的序列將被隱藏。用戶將僅僅看到一個序列列表而不是一個儲存序列指的表,而在 MySQL 中這就是序列是如何被模擬的。而且 MDB_frontend 將幫助移植已經存在的數據庫來符合 MDB 預期使用的原生數據類型。它還將幫助創建和更新 XML schema 文件。一些初期的工作已經完成了但是很多工作需要在公開發布之前被添加。
驅動和 MDB_frontend 是當前開發的所有焦點,在 MDB 中還有許多用戶可能需要的:像 bulk 獲取 LOB 域的集成,其他人可能需要外部和主鍵支持。如一直以來的那樣如果你參與測試和實現,開源的東西將加快很多。但是我也很感謝像特性需求合陽的反饋。
一些文后的思考
在數月的艱辛工作之后,MDB 正在當前的 PEAR DB 和 Metabase 用戶中獲得認可。我還希望當前還沒有被其他數據庫抽象層說服的用戶意識到 MDB 給他們的好處。當然,還是有許多程序需要對 RDBMS 進行特殊剪裁,對于這種情況像 MDB 這樣的工具僅僅是增加了不必要的額外負擔和限制。總的來說,我非常高興我們在我們的公司中作出領導 MDB 開發的決定。在起初,我對嘗試同時取悅 PEAR DB 和 Metabase 的用戶但是結果可能到處不討好多少有些擔心。另外一個關心的來源是 PHP 社區是否將幫助其開發。我非常高興 PHP 社區來了并且幫助撰寫驅動以及 MDB 的核心。因而我們認為這個項目是一個極大的成功。我們還一并相信 MDB 將得到更大的改進。而且我們對幫助 PHP 變得更好感到高興。
關于作者
Lukas Smith 是 PEAR DB 的主要作者。它積極地給多個 PHP 開遠項目進行貢獻并且是專注于 PHP 開發的 BackendMeida 公司的建立者。
鏈接 和 文獻
PEAR MDB homepage: http://pear.php.net/package-info.php?package=MDB
PEAR MDB documentation: http://www.backendmedia.com/MDB/docs/
PEAR MDB sample script: http://cvs.php.net/co.php/pear/MDB/MDB_test.php
PEAR DB homepage: http://pear.php.net/package-info.php?package=DB
Metabase homepage: http://www.phpclasses.org/mirrors.html?page=%2Fbrowse.html%2Fpackage%2F20.html
Simple benchmark: http://freshmeat.net/screenshots/30313/