2009年7月20日 星期一

就讓 C 語言和 Sqlite3 擦出火花吧

Standard
電腦科技發展至今,就屬資料的處理、建檔和搜尋貢獻於人類最大,隨處可見 database 應用範疇,且各種 SQL Server 早就犯濫成災,不管大小事都要建置一個 database 去處理。但是,很多時候其實用不到龐大的 database server,如:個人用通訊錄或在 Embedded System 上的程式應用,因為並沒有這麼多的資料量需要被處理,因此若架設個 server 也未免小題大作,不但浪費系統資源,也拖慢程式的效能,此時一個小型又輕量的 database solution 就正是我們所需要。

目前已經有許多小型的 database 解決方案如:dbm、Berkeley DB、Sqlite,更早以前還有 Microsoft Office 系列中的 Access。開發者可以依照需求選擇適合的方案使用,但對於熟悉 SQL 的人來說,能支援大部份 SQL92 標準的 Sqlite ,還是最受親睞。Sqlite 就因為有 SQL 的特性,又兼具輕巧,常被拿去使用於 Embedded system 和當成各種軟體的資料處理機制,例如眾所皆知的 Firefox ,其 backend 就是 Sqlite。

使用 C 語言開發 Sqlite 的程式非常容易,短短數行就可以完成:
#include <stdio.h>
#include <sqlite3.h>

static char *createsql = "CREATE TABLE Contact("
"ID INTEGER PRIMARY KEY,"
"Name VARCHAR(10),"
"PhoneNumber VARCHAR(10));";

static char *insertsql = "INSERT INTO Contact VALUES(NULL, 'Fred', '09990123456');";

static char *querysql = "SELECT * FROM Contact;";

void main(void)
{
int rows, cols;
sqlite3 *db;
char *errMsg = NULL;
char **result;

/* 開啟 database 檔 */
if (sqlite3_open_v2("example.db3", &db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL)) {
return;
}

/* 建立 Table */
sqlite3_exec(db, createsql, 0, 0, &errMsg);

/* 新增一筆資料 */
sqlite3_exec(db, insertsql, 0, 0, &errMsg);
/* 取得該筆資料的 ID */
printf("%d\n", sqlite3_last_insert_rowid(db));

/* 取得 database 裡所有的資料 */
sqlite3_get_table(db , querysql, &result , &rows, &cols, &errMsg);

/* 列出所有資料 */
for (i=0;i<rows;i++) {
for (j=0;j<cols;j++) {
printf("%s\t", result[i*cols+j]);
}
printf("\n");
}

/* 釋放 */
sqlite3_free_table(result);

/* 關閉 database */
sqlite3_close(db);
}


Compile 時只要加上 sqlite 的 flag:
gcc  -lsqlite3  -o sqlite_ex sqlite_ex.c


雖然 Sqlite 很好用,又不需要什麼 dependency,隨處都可輕易使用。不過也要適時考慮程式需要處理的資料量,再決定是否使用 Sqlite,不然最終將導致和 Firefox 的同樣下場 - 越來越慢。