2010年10月22日 星期五

SQLite介紹

(一) SQLite介紹



SQLite第一個Alpha版本誕生於2000年5月. 至今已經有4個年頭了. 而在今年的5月SQLite也迎來了一個新的里程: SQLite 3.

下面是你訪問SQLite官方網站: www.sqlite.org 時第一眼看到關於SQLite的特性.



1. ACID事務

2. 零配置 – 無需安裝和管理配置

3. 儲存在單一磁盤文件中的一個完整的數據庫

4. 數據庫文件可以在不同字節順序的機器間自由的共享

5. 支持數據庫大小至2TB

6. 足夠小, 大致3萬行C代碼, 250K

7. 比一些流行的數據庫在大部分普通數據庫操作要快

8. 簡單, 輕鬆的API

9. 包含TCL綁定, 同時通過Wrapper支持其他語言的綁定

10. 良好註釋的源代碼, 並且有著90%以上的測試覆蓋率

11. 獨立: 沒有額外依賴

12. Source完全的Open, 你可以用於任何用途, 包括出售它



從代碼架構圖你可以輕鬆的看出, 是的, SQLite非常簡單. 對, SQLite的設計思想就是簡單:

1. 簡單的管理

2. 簡單的操作

3. 簡單的在程序中使用它

4. 簡單的維護和客制化

因為簡單所以它快速, 但雖然簡單, 卻仍非常可靠. 適合SQLite的應用場所有, 網站,嵌入式設備和應用, 應用程序文件格式, 代替特別的文件, 內部或臨時數據庫, 命令行數據集分析工具, 在演示或測試中代替企業級數據庫, 數據庫教學, 試驗SQL語言擴展等. 但並不是所有都合適, 比如在使用Server/Client結構的時候,高負荷的網站,高並發等情況下並不建議使用SQLite.

本文重點在於介紹SQLite在PHP中的應用, PHP作為Web應用中一個重要力量一直在不斷的前進和發展. 在馬上就要Release的PHP的第五個版本中, 不再將MySQL作為默認支持, 而轉為將SQLite的擴展作為默認支持. 從某種程度上說MySQL的廣泛應用有PHP的很大功勞. 雖然說PHP改變默認支持有MySQL的授權改變的原因, 但選擇SQLite也是有原因的, 理由就在於上面所提到的那些特性. 其實MySQL從來就不是完全免費的, 你無法用於商業用途. 而SQLite是完全的open的.



(二) SQLite SQL

SQLite的SQL從很大程度上實現了ANSI SQL92標準. 特別的SQLite支持視圖, 觸發器, 事務, 支持嵌套SQL. 這些都會在下面應用的過程中講到, 故這邊先暫時放下, 而主要說說SQLite所不支持的一些SQL.

1. 不支持Exists, 雖然支持in(in是Exists的一種情況)

2. 不支持多數據庫, 如: create table db1.table1 as select * from db2.table1;

3. 不支持存儲過程

4. 不支持Alter View/Trigger/Table

5. 不支持Truncate, 在SQLite中Delete不帶Where字句時和Truncate的效果是一樣的.

6. 不支持Floor和Ceiling函數, 還有其他蠻多的函數

7. 沒有Auto Increment(自增)字段, 但是SQLite其實是支持Auto Increment的, 即在將該字段設置為」 INTEGER PRIMARY KEY」的時候.

8. 不支持If Exists

……

詳細的SQL支持可以訪問: http://www.sqlite.org/lang.htm

詳細的不支持SQL可以訪問: http://www.sqlite.org/cvstrac/wiki?p=UnsupportedSql



(三) SQLite的數據類型



首先你會接觸到一個讓你驚訝的名詞: Typelessness(無類型). 對! SQLite是無類型的. 這意味著你可以保存任何類型的數據到你所想要保存的任何表的任何列中, 無論這列聲明的數據類型是什麼(只有在一種情況下不是, 稍後解釋). 對於SQLite來說對字段不指定類型是完全有效的. 如:



Create Table ex1(a, b, c);




誠然SQLite允許忽略數據類型, 但是仍然建議在你的Create Table語句中指定數據類型. 因為數據類型對於你和其他的程序員交流, 或者你準備換掉你的數據庫引擎. SQLite支持常見的數據類型, 如:



CREATE TABLE ex2(

a VARCHAR(10),

b NVARCHAR(15),

c TEXT,

d INTEGER,

e FLOAT,

f BOOLEAN,

g CLOB,

h BLOB,

i TIMESTAMP,

j NUMERIC(10,5)

k VARYING CHARACTER (24),

l NATIONAL VARYING CHARACTER(16)

);


前面提到在某種情況下, SQLite的字段並不是無類型的. 即在字段類型為」Integer Primary Key」時.



(四) SQLite的Wrapper



由於SQLite有別於其他數據庫引擎的TCP/IP或RPC訪問方式, 完全地是本地的操作, 從某種角度來說你可以說SQLite和MS的Access很相似, 但是更小更強大. 所謂Wrapper即使對SQLite提供的接口進行封裝, 使其他語言可以訪問, 使用SQLite.

SQLite本身是提供C和Tcl的接口的. 所以可以非常輕易的和PHP相結合. 除了PHP的Wrapper以外, 還有許多世界各地的程序員提供了各種語言的SQLite的接口封裝, 如Python, C++, Java, .Net…… 所流行的語言基本都有.



(五) PHP的環境下使用SQLite



1. PHP下的安裝

在PHP5中, SQLite已作為默認支持的模塊.在PHP4中你需要進行安裝. 首先去http://pecl.php.net/package/SQLite 去下載到SQLite的擴展, 注意Windows下的版本需要去http://snaps.php.net/win32/PECL_STABLE/php_sqlite.dll 下載, 當然你也可以下載代碼自己編譯.事實上在linux下只需要使用命令: 『pear install sqlite』就可以完成安裝,而在Win下需要修改php.ini, 同樣的使PHP4支持SQLite.

此時你已經無需再安裝任何東西了, 而你也已經完全支持SQLite了, 一個簡單, 快速, 可靠的數據庫.

如果你需要一個管理軟件, 那麼你可以嘗試使用SQLiteManager (www.sqlitemanager.org), 一個與PHPMyAdmin類似的針對SQLite的數據庫管理系統.

該系統的界面大致如下:



2. 第一個使用SQLite的PHP程序.

我們創建一個叫binzy的數據庫, 並創建一個叫Binzy的Table, 有2個字段, 分別是ID, Title. 而其中ID為INTEGER PRIMARY KEY, 即自增三主鍵. 並在其中插入了2條數據」Binzy」, 「Jasmin」.

打開並顯示數據:

if ($db = sqlite_open('../binzy.db', 0666, $sqliteerror))

{ // 打開

SQLite$result = sqlite_query($db,'select * from Binzy'); // 查詢while($row = sqlite_fetch_array($result)) // 獲得結果

{

print 'ID=>'.$row['MyID'].', Name=>'.$row['Name'].'
';

}

} else {die ($sqliteerror);}


結果如下,



接下來Insert一條記錄, 其中我們會使用到SQLite的事務.



if ($db = sqlite_open('../binzy.db', 0666, $sqliteerror)) {



sqlite_query($db,'BEGIN TRANSACTION'); // 開始事務

if (@sqlite_query($db,'insert into Binzy (Name) values (\'Binzy&Jasmin\')'))

{

print 'Execute Successfully';

sqlite_query($db,'COMMIT TRANSACTION'); // 提交事務

}

else

{

print sqlite_error_string(sqlite_last_error($db));

sqlite_query($db,'ROLLBACK TRANSACTION'); // 回滾事務

}

} else {

die ($sqliteerror);

}


如果執行失敗, 便會出現這樣的畫面,





成功則是這樣的,



是的, 如果你已經熟悉使用PHP對MySQL之類的數據庫進行操作, 那麼SQLite幾乎是一樣的, 而且更為簡潔.



3. 使用Pear::DB (PHP4中)

上面的例子中我們是使用PHP的函數直接對SQLite進行訪問, 這樣的訪問方式是不推薦使用的. 更好的方式是使用某種數據訪問抽像層, 如Pear的DB. 下面是2中查詢例子的重寫. 使用某個數據訪問抽像層會更方便更安全, 並且可以在需要進行數據庫遷移的時候盡可能減小成本.

require_once('DB.php');

$dbh = DB::connect('sqlite://@localhost/../binzy.db?mode=0666'); // 打開

$dbh->setFetchMode(DB_FETCHMODE_ASSOC);

if (!DB::isError($dbh))

{

$result = $dbh->query('select * from Binzy'); // 查詢

if (!DB::isError($result))

{

while($row = $result->fetchRow()) // 讀取

{ print 'ID=>'.$row['MyID'].', Name=>'.$row['Name'].'
';

}

$dbh->disconnect();

}

else

{

print($dbh->message);

$dbh->disconnect();

}

}

else

{

print($dbh->message);

$dbh->disconnect();

}




4. 使用Creole (PHP5中)

Creole是由phpdb.org開發的面向PHP5的數據訪問抽像層. 關於Creole可參考本期中的《Creole :新興數據抽像層》.

Pear::DB並沒有針對PHP5進行改變, 只是因為PHP5對PHP4良好的兼容性, 使得Pear::DB在PHP5下仍能很好的工作. 所以在你使用PHP5的時候推薦使用Creole.

require_once('creole/Creole.php');

$Connection = null;

try{

$Connection = Creole::getConnection('sqlite://@localhost/../binzy.db?mode=0644'); // 獲得Connection

$rs = $Connection->executeQuery('select * from Binzy'); // Get ResultSet while($rs->next())

{

print 'ID=>'.$rs->getInt('myid').', Name=>'.$rs->getString('name').'
';

}

$Connection->close();

}

catch(SQLException $exception) // Catch Exception

{

$Connection->close();

print $exception->getMessage();

}




(六) 總結



隨著PHP5的即將到來, 給我們帶來了許多新的語言特性, 使PHP更加適合於構建強大健壯的各類系統. 而隨著PHP5一起走進PHP開發人員視線的SQLite則給我們帶來了有別於MySQL的驚喜. 是的, 他簡單卻又強大, 穩定. 而在剛剛過去的六月底新版本的SQLite3已經Release了第一個測試版本, 不僅僅帶來了新的文件結構, 也帶來了許多新的特性.

沒有留言:

wibiya widget