【摘要】在對移動嵌入式數(shù)據(jù)庫中BLOB數(shù)據(jù)類型分析的基礎(chǔ)上,使用C語言的API函數(shù)調(diào)用移動SQLite數(shù)據(jù)庫語句,并按其訪問模式調(diào)用連接函數(shù),實(shí)現(xiàn)了SQLite移動數(shù)據(jù)庫中二進(jìn)制大對象和C結(jié)構(gòu)體類型數(shù)組的BLOB處理方法。隨著圖像和音視頻數(shù)據(jù)的日益增多,BLOB數(shù)據(jù)類型在SQLite中的應(yīng)用將更為廣闊,給出的Demo實(shí)例驗(yàn)證了這一技術(shù)的有效性。
【關(guān)鍵詞】SQLite移動數(shù)據(jù)庫BLOB類型嵌入式開發(fā)
中圖分類號:TP311文獻(xiàn)標(biāo)識碼:A文章編號:1006-1010(2014)-08-0061-04
Application of BLOB Data Type in SQLite Mobile Embedded Database
LIU Yu-hai
(College of Mining Technology, Taiyuan University of Technology, Taiyuan 030024, China)
[Abstract] Based on the analysis of BLOB data type in mobile embedded database, the API function of C language calls mobile SQLite database statements and connection function is called according to its access mode, which achieves BLOB method of binary large objects and C structure array in SQLite mobile database. With the increase of images as well as audio and video data, the application of BLOB data type in SQLite will be broader. Demo examples are given to verify the effectiveness of this technology.
[Key words]SQLite mobile databaseBLOB typeembedded development
1 引言
移動嵌入式數(shù)據(jù)庫一直是一個熱點(diǎn)應(yīng)用開發(fā),作為輕量級嵌入式移動數(shù)據(jù)庫的典型,SQLite有許多令人印象深刻的優(yōu)點(diǎn),包括:具有開放源代碼;自身程序特別??;支持大多數(shù)SQL命令;速度極快;直接創(chuàng)建數(shù)據(jù)庫,不需要服務(wù)器支持;簡潔的C語言API(Application Programming Interface,應(yīng)用程序編程接口)接口。它具有的零配置安裝可在系統(tǒng)崩潰或電源故障時自動恢復(fù),且數(shù)據(jù)被存儲在單一的物理文件中,數(shù)據(jù)庫運(yùn)行在同一個相互間無通信的進(jìn)程,訪問數(shù)據(jù)庫的程序直接從文件讀取和寫入磁盤,數(shù)據(jù)的讀寫速度快,具有高達(dá)2TB的存儲容量,在提供了存儲BLOB(Binary Large Object,二進(jìn)制大對象)方法的同時,API擴(kuò)展等也提供了強(qiáng)有力的技術(shù)支撐;存儲在SQLite數(shù)據(jù)庫BLOB數(shù)據(jù)類型的輸入數(shù)據(jù)無需任何轉(zhuǎn)換,數(shù)據(jù)本身的屬性就是表的列屬性[1]。
2 BLOB技術(shù)原理
BLOB數(shù)據(jù)類型是適合用于存儲可變長度的二進(jìn)制大對象數(shù)據(jù)以及可變長度的音頻和視頻數(shù)據(jù)。在SQLite的BLOB類型中存儲復(fù)雜的數(shù)據(jù)時,長度是不加限制的[2]。使用B-樹索引來管理和組織屬性數(shù)據(jù),通過SQL語句到數(shù)據(jù)庫相關(guān)數(shù)據(jù)中實(shí)現(xiàn)增、刪、改、查的操作。SQLite不支持靜態(tài)數(shù)據(jù)類型,而是使用列關(guān)系。當(dāng)數(shù)據(jù)記錄的字段內(nèi)容插入到數(shù)據(jù)庫中時,SQLite將對該字段內(nèi)容的類型做檢查,若類型不能匹配到相關(guān)聯(lián)的列,則SQLite會將該字段內(nèi)容轉(zhuǎn)換成列的類型。因此,數(shù)據(jù)庫中BLOB數(shù)據(jù)類型的合理應(yīng)用也直接影響存儲效率和查詢速度的提高。
3 BLOB類型在SQLite中的應(yīng)用
3.1SQLite的API函數(shù)
嵌入式移動數(shù)據(jù)庫SQLite使用C語言API等接口,在此基礎(chǔ)上的擴(kuò)展也可用于其他語言的SQLite的接口[3]。以下是SQLite中常用的對數(shù)據(jù)庫進(jìn)行操作的函數(shù):
(1)創(chuàng)建和打開數(shù)據(jù)庫
int sqlite3_open(const char*,sqlite3**db);
功能是當(dāng)數(shù)據(jù)庫文件存在時,可以打開已存在的數(shù)據(jù)庫;若不存在,則創(chuàng)建一個新的數(shù)據(jù)庫文件并打開,且能通過輸入?yún)?shù)返回連接。
(2)運(yùn)行函數(shù)
int sqlite3_exec(sqlite3*,const char*sql,sqlite_callback,void*,char**em);
*sql是運(yùn)行的SQL語句,該語句可按實(shí)際需要編寫一條或多條;sqlite_callback是一個回調(diào)函數(shù),根據(jù)實(shí)際可編寫回調(diào)函數(shù)從數(shù)據(jù)庫中獲取需要的結(jié)果。
(3)預(yù)編譯SQL語句的函數(shù)
int sqlite3_prepare(sqlite3*db,const char*iSql,int jByte,sqlite3_stmt**pStmt,const char**pl);
該函數(shù)需要一個數(shù)據(jù)庫連接的指針,將給定的SQL文本轉(zhuǎn)換為預(yù)聲明語句對象并返回一個指向它的指針,這個函數(shù)并不執(zhí)行SQL語句,只是預(yù)編譯和解析SQL文本,準(zhǔn)備執(zhí)行。
(4)查詢函數(shù)
int sqlite3_get_table(sqlite3*,const char*sql,char ***ret,int*nrow,int*ncol,char**em);
功能是無需回調(diào)函數(shù)處理,直接能查詢結(jié)果集。
3.2SQLite數(shù)據(jù)庫BLOB類型應(yīng)用實(shí)例
(1)SQLite二進(jìn)制大對象處理技術(shù)
在實(shí)際編程開發(fā)中,往往是進(jìn)行二進(jìn)制大對象數(shù)據(jù)的訪問,如圖像、音視頻等。對于這些數(shù)據(jù)不能像對待普通的文本一樣插入或查詢那樣簡單,而是將圖像等文件在使用Insert或Update語句時先用通配符‘?代替,通配符‘?表示未定值是一個占位符,然后通過sqlite3_bind_blob綁定到Insert或Update中,替換‘?部分并存儲。如果是字符串,則還需要通過sqlite3_bind_parameter_index()獲取對應(yīng)的index,然后再調(diào)用sqlite3_bind_blob()操作。通常也用于構(gòu)造不定條件的動態(tài)SQL語句。
以下的Demo1.c程序就實(shí)現(xiàn)了SQLite數(shù)據(jù)庫中圖像的存取處理[4]:
//創(chuàng)建表函數(shù)
int CreateTab(sqlite3*db)
{char*EM=0; //*EM指針返回錯誤消息
char*sql="CREATE TABLE xuch(BH primart key,MC varchar(10),SL int,SB blob); "
if(SQLITE_OK)!=sqlite3_exec(db, 0,0,&EM))
{printf(" failed:%s ",EM);}
endprint
}
//插入數(shù)據(jù)記錄并處理大對象數(shù)據(jù)函數(shù)
int InsertRec(sqlite3*db)
{……
char*sql="INSERT INTO xuch(BH,MC,SL) VALUES(‘20121001,Computer,20); "
……
char*sql="UPDATE xuch SET SB=? WHERE MC='Computer';" //‘?通配符是占位符代替二進(jìn)制文件
}
……//此處需應(yīng)有為占位符‘?所提供的圖像視頻等大對象文件的打開等操作
sqlite3_bind_blob(stmt, 1, fl, fs, NULL);//調(diào)用該函數(shù)使Update中‘?代表的參數(shù)傳入對應(yīng)字段,其中的stmt記錄了SQL語句
如果有多個‘?,就需要寫出多個sqlite3_bind_blob語句,并改變它們的第2個參數(shù)即可替換到不同的‘?。最后使用sqlite3_step將二進(jìn)制數(shù)據(jù)保存到對應(yīng)的數(shù)據(jù)庫中。
(2)C結(jié)構(gòu)體類型在BLOB中的處理技術(shù)
將一個結(jié)構(gòu)體數(shù)據(jù)以二進(jìn)制的方式寫入到SQLite數(shù)據(jù)庫的BLOB類型中,并顯示出結(jié)果。
Demo2.c程序主要代碼如下所示,其中personal是一個結(jié)構(gòu)體數(shù)組。
sqlite3*db;
sqlite3_open("test.db", &db);
sqlite3_stmt*stmt;
typedef struct xuchunhua
{???????int?no;
char?name[10];
bool?sex;
}teacher;
teacher?personal[20];
……
personal[1].no=10;
strcpy(personal[1].name,“LiuBing”);
personal[i].bool=1;
……
result=sqlite3_exec(db,"create?table?xuch(bh?text,jg?blob)", 0,0,&perrmsg); //創(chuàng)建對應(yīng)的表,這里用到了blob類型
result=sqlite3_prepare(db,"insert?into?xuch values(?,?)",-1,&stmt,0); //插入數(shù)據(jù),這里采用預(yù)編譯的形式,凡是二進(jìn)制的數(shù)據(jù)都要這樣處理[5]
……
void*buffer?;? //創(chuàng)建內(nèi)存指針
buffer=new?char(sizeof(teacher)); //初始化存儲空間,sizeof(teacher)為結(jié)構(gòu)體大小
……
result=sqlite3_bind_text(stmt,1,“X1001”, -1,NULL); //綁定表的第一個字段,這里為text類型
result=sqlite3_bind_blob(stmt,2,buffer,sizeof(teacher),NULL); //綁定blob類型
result=sqlite3_step(stmt); //執(zhí)行sql語句,這樣就把數(shù)據(jù)存到數(shù)據(jù)庫里了
……
result=sqlite3_prepare(db,"select?jg?from?xuch
where?bh=“X1001”,-1,&stmt,0); //查找一行的數(shù)據(jù)
result=sqlite3_step(stmt);
if(result==SQLITE_ROW)
{
int?blob_size=sqlite3_column_bytes(stmt,0)/sizeof(teacher); //獲取數(shù)組的長度
personal1=(teacher*)sqlite3_column_blob(stmt,0); //獲取數(shù)組的頭指針
for(int?i=0?;i {printf("%d",personal[i].sno); printf("%s",personal[i].sname; //輸出數(shù)據(jù) } sqlite3_finalize(stmt); sqlite3_close(db); 4 結(jié)束語 SQLite提供了存取二進(jìn)制大對象BLOB的方法,在嵌入式移動數(shù)據(jù)庫開發(fā)中,可對二進(jìn)制大對象和C結(jié)構(gòu)體使用BLOB類型數(shù)據(jù)處理。SQLite移動數(shù)據(jù)庫的設(shè)計(jì)目標(biāo)是嵌入式的,而且目前已經(jīng)在很多嵌入式產(chǎn)品中使用,它占用的資源非常低。SQLite嵌入式移動數(shù)據(jù)庫的易用性,可加快應(yīng)用程序的開發(fā),完全支持復(fù)雜的SQL,對于小型設(shè)備的有限空間來說是特別重要的應(yīng)用。此外,SQL還支持原子的、一致的、獨(dú)立的和持久的(ACID)事務(wù)。SQLite允許多個進(jìn)程同時打開一個數(shù)據(jù)庫,同時讀取數(shù)據(jù)庫實(shí)現(xiàn)并發(fā)處理。隨著應(yīng)用的廣泛,在移動數(shù)據(jù)庫中具有越來越多的圖像數(shù)據(jù)、大文本數(shù)據(jù)、音頻和視頻數(shù)據(jù),在SQLite中BLOB數(shù)據(jù)類型的應(yīng)用將更為廣闊。 參考文獻(xiàn): [1] Michael Owens. The Definitive Guide to SQLite[M]. Berkeley: Apress, 2006. [2] 葉宏祥. 移動存儲關(guān)鍵性技術(shù)的研究及進(jìn)展[J]. 移動通信, 2009(11): 32-34. [3] The Architecture of SQLite[EB/OL]. [2013-08-21]. http://www.sqlite.org/arch.html. [4] 劉玉海,劉冰. SQLite嵌入式數(shù)據(jù)庫及圖象處理技術(shù)研究[J]. 軟件, 2012(8): 102-104. [5] C/C++ Interface for SQLite Version3[EB/OL]. [2013-08-21]. http://www.sqlite.org/capi3ref.html.★ 作者簡介 劉玉海:高級工程師,現(xiàn)任職于太原理工大學(xué)礦業(yè)工程學(xué)院,主要研究方向?yàn)閿?shù)據(jù)庫及應(yīng)用系統(tǒng)開發(fā)。