基于ARM-Linux的SQLite嵌入式數(shù)據(jù)庫(kù)的研究
掃描二維碼
隨時(shí)隨地手機(jī)看文章
關(guān)鍵詞:嵌入式數(shù)據(jù)庫(kù);SQLite;ARM-Linux平臺(tái);交叉編譯
Abstract :SQLite is an open source embedded SQL database engine. At first,descripe some general databases’ technology in this paper, and then Internal architecture and developing method of SQLite are analyzed. The application developing ,cross compiling and porting in ARM-Linux platform are also introduced and a detailed example is given for presentation.
Keywords :Embedded Databese; SQLite; ARM-Linux platform; cross compiling
引言
隨著嵌入式系統(tǒng)的廣泛應(yīng)用和用戶對(duì)數(shù)據(jù)處理和管理需求的不斷提高,各種智能設(shè)備和數(shù)據(jù)庫(kù)技術(shù)的緊密結(jié)合已經(jīng)得到了各方面的重視。不久的將來(lái)嵌入式數(shù)據(jù)庫(kù)將無(wú)處不在??v觀目前國(guó)際、國(guó)內(nèi)嵌入式數(shù)據(jù)庫(kù)的應(yīng)用情況,目前基于嵌入式數(shù)據(jù)庫(kù)應(yīng)用的市場(chǎng)已經(jīng)進(jìn)入加速發(fā)展的階段。
1 嵌入式數(shù)據(jù)庫(kù)
1.1 嵌入式數(shù)據(jù)庫(kù)的設(shè)計(jì)
嵌入式數(shù)據(jù)庫(kù)系統(tǒng)是指支持某種特定計(jì)算模式或移動(dòng)計(jì)算的數(shù)據(jù)庫(kù)管理系統(tǒng),它通常與操作系統(tǒng)和具體應(yīng)用集成在一起,運(yùn)行在智能型嵌入式設(shè)備或移動(dòng)設(shè)備上。嵌入式數(shù)據(jù)庫(kù)的使用是采用程序驅(qū)動(dòng),即由程序調(diào)用相應(yīng)的API來(lái)實(shí)現(xiàn)數(shù)據(jù)的存取。具有體積小巧、快速高效、穩(wěn)定可靠、可移植性等特點(diǎn),非常適用于嵌入式環(huán)境下的數(shù)據(jù)管理.。
嵌入式數(shù)據(jù)庫(kù)的主要設(shè)計(jì)思想如下圖1所示,在向上層應(yīng)用提供標(biāo)準(zhǔn)的數(shù)據(jù)庫(kù)接口的同時(shí),擺脫傳統(tǒng)數(shù)據(jù)庫(kù)僅僅由軟件驅(qū)動(dòng)的束縛,根據(jù)嵌入式系統(tǒng)的實(shí)際情況用SOC技術(shù)同時(shí)實(shí)現(xiàn)硬件驅(qū)動(dòng)。軟件部分按SQL92標(biāo)準(zhǔn)實(shí)現(xiàn)SQL語(yǔ)句的解析,實(shí)現(xiàn)事務(wù)管理功能、數(shù)據(jù)同步機(jī)制、數(shù)據(jù)的備份和恢復(fù),軟件部分不關(guān)心數(shù)據(jù)的實(shí)際存儲(chǔ),用標(biāo)準(zhǔn)C實(shí)現(xiàn),能同任何嵌入式操作系統(tǒng)內(nèi)核一同編譯,能支持各嵌入式操作系統(tǒng)的安裝格式,由數(shù)據(jù)庫(kù)硬件驅(qū)動(dòng)專(zhuān)用芯片實(shí)現(xiàn)對(duì)實(shí)際數(shù)據(jù)的訪問(wèn)功能(存儲(chǔ)器讀寫(xiě),I/O通訊,異構(gòu)數(shù)據(jù)庫(kù)接駁)。
圖1 嵌入式數(shù)據(jù)庫(kù)驅(qū)動(dòng)結(jié)構(gòu)圖
1.2. 嵌入式數(shù)據(jù)庫(kù)SQLite
SQLite 是D. Richard Hipp 在2000年開(kāi)發(fā)的一個(gè)小型嵌入式數(shù)據(jù)庫(kù)。他是完全獨(dú)立的,不具有外部依賴(lài)性,可以較為方便地應(yīng)用于嵌入式系統(tǒng)中。其源代碼完全開(kāi)放,可以免費(fèi)用于任何用途,包括商業(yè)目的。SQLite 雖然是個(gè)極端輕量級(jí)的關(guān)系數(shù)據(jù)庫(kù),卻保留了數(shù)據(jù)庫(kù)的大部分特征,他提供了對(duì)SQL92 標(biāo)準(zhǔn)的大多數(shù)支持:支持多表和索引、事務(wù)、視圖、觸發(fā)和一系列的用戶接口及驅(qū)動(dòng)。其主要特征如下::
(1) 支持原子的、一致的、獨(dú)立的和持久的(ACID) 事務(wù)特性,即使系統(tǒng)崩潰和掉電。
(2) 零配置(Zero2configuration),無(wú)需安裝和管理。
(3) 一個(gè)完整的數(shù)據(jù)庫(kù)存儲(chǔ)在單一磁盤(pán)文件中。
(4) 數(shù)據(jù)庫(kù)文件可以在不同字節(jié)順序的機(jī)器間自由共享。
(5) 支持?jǐn)?shù)據(jù)庫(kù)大小至2 TB。
(6) 字符串和二進(jìn)制大對(duì)象(BLOBs) 的大小僅被有效內(nèi)存限制。
(7) 源碼體積小,編譯后低于250 kB。
(8) 大部分的操作比關(guān)系型數(shù)據(jù)庫(kù)引擎要快。
(9) 簡(jiǎn)單易用的API。
SQLite 由于小、快、簡(jiǎn)單、可靠,而且作者完全放棄版權(quán),從他一發(fā)布出來(lái),便深受歡迎。對(duì)于嵌人式環(huán)境,管理、執(zhí)行、維護(hù)的簡(jiǎn)單化比企業(yè)數(shù)據(jù)庫(kù)引擎提供的許多復(fù)雜應(yīng)用更重要,因此SQLite 數(shù)據(jù)庫(kù)是一個(gè)很好的選擇。
2 SQLite 內(nèi)部結(jié)構(gòu)及開(kāi)發(fā)技術(shù)
2. 1 SQLite 內(nèi)部結(jié)構(gòu)
SQLite 采用模塊化的設(shè)計(jì),主要由4個(gè)部分組成:內(nèi)核(Core)、SQL編譯器( SQL Compiler)、后端(Backend)以及附件(Accessories)。內(nèi)部結(jié)構(gòu)如圖2所示。
圖2 SQLite 的內(nèi)部結(jié)構(gòu)
SQLite 的接口是一些已經(jīng)編寫(xiě)好的C庫(kù),即使使用不同語(yǔ)言的API,在底層仍然使用C 庫(kù)執(zhí)行。SQL語(yǔ)句通過(guò)接口進(jìn)入到高效的SQL編譯器,由標(biāo)記處理器( tokeni2zer)分解成檸檬分析器(par ser) 可以識(shí)別的各個(gè)標(biāo)志符,然后由分析器重新組合標(biāo)志符并調(diào)用代碼生成器(code generator) 生成虛擬機(jī)器碼,交由虛擬機(jī)( virtual machine)去執(zhí)行,最終完成SQL 語(yǔ)句指定的任務(wù)。虛擬機(jī)是SQLite 內(nèi)部結(jié)構(gòu)的核心,不僅完成與數(shù)據(jù)操作相關(guān)的全部操作,而且還是客戶和存儲(chǔ)之間信息進(jìn)行交換的中間單元。數(shù)據(jù)庫(kù)按照B樹(shù)(B2t ree) 的形式存儲(chǔ)在磁盤(pán)上,通過(guò)可調(diào)整的頁(yè)面緩沖(pager) 獲得對(duì)數(shù)據(jù)的快速查找和存儲(chǔ)。為了方便移植,SQLite 使用一個(gè)抽象層接口(OS in2terface) 與不同操作系統(tǒng)進(jìn)行對(duì)接。
2. 2 SQLite 開(kāi)發(fā)技術(shù)
SQLite 本身提供了C 語(yǔ)言的API 接口,使得對(duì)數(shù)據(jù)庫(kù)的操作十分簡(jiǎn)單,主要是對(duì)3個(gè)API 函數(shù)的調(diào)用。
(1) 打開(kāi)數(shù)據(jù)庫(kù)
int sqlite3 open (
const char 3 filename , / 3 數(shù)據(jù)庫(kù)文件名(U TF28) 3 /
sqlite3 3 3 ppDb / 3 輸出SQLite 數(shù)據(jù)庫(kù)句柄3 /
) ;
(2) 執(zhí)行SQL
int sqlite3 exec (
sqlite3 3 , / 3 已經(jīng)打開(kāi)的數(shù)據(jù)庫(kù)句柄3 /
const char 3 sql , / 3 要執(zhí)行的SQL 語(yǔ)句3 /
sqlite callback , / 3 回調(diào)函數(shù)3 /
void 3 , / 3 回調(diào)函數(shù)的第一個(gè)參數(shù)3 /
char 3 3 errmsg / 3 錯(cuò)誤信息返回3 /
) ;
(3) 關(guān)閉數(shù)據(jù)庫(kù)
int sqlite3 close ( sqlite3 3 ) ; / 3 參數(shù)就是打開(kāi)時(shí)的結(jié)構(gòu)體,即數(shù)據(jù)庫(kù)句柄3 /
其中,sglite3 exec ( ) 函數(shù)的第二個(gè)參數(shù)用來(lái)處理一條或多條SQL 語(yǔ)句,語(yǔ)句間必須用“;”號(hào)隔開(kāi)。如果是查詢(SEL ECT) 語(yǔ)句,查詢結(jié)果的每一條記錄都必須調(diào)用第三個(gè)參數(shù)的Callback 函數(shù),第四個(gè)參數(shù)則為Callback 函數(shù)的第一個(gè)參數(shù)指針。如果不是查詢語(yǔ)句,第三、四個(gè)參數(shù)為NULL。所有SQL 執(zhí)行完畢后返回0,否則返回錯(cuò)誤代碼,可通過(guò)第五個(gè)參數(shù)值來(lái)查看詳細(xì)錯(cuò)誤信息。
3 SQLite 在ARM-Linux 平臺(tái)上的實(shí)現(xiàn)
SQLite 嵌入式數(shù)據(jù)庫(kù)提供了以源碼發(fā)布的方式,要在眾多的硬件平臺(tái)進(jìn)行移植,可以根據(jù)不同平臺(tái)對(duì)源碼進(jìn)行交叉編譯來(lái)實(shí)現(xiàn)。編譯主要有以下幾個(gè)步驟:
① 到http :/ / www. sqlite. org/ 的cvs中下載最新的源代碼包,解壓并根據(jù)需要進(jìn)行適當(dāng)?shù)男薷暮髮⑸蓅qlite目錄,另外新建并轉(zhuǎn)到一個(gè)與sqlite目錄平行的同級(jí)目錄,如make目錄。
②用“echo $PATH”命令查看PATH中是否已經(jīng)包含交叉編譯工具arm linux gcc。
③為了在ARM Linux下能正常運(yùn)行sqlite,需要對(duì)sqlite/ src/ sqliteInt . h作一定的修改,以確保bt ree (B 樹(shù))有正確的變量大小,如“pt r”和“char 3 ”。不同體系結(jié)構(gòu)的Linux,如x86 和ARM,會(huì)有些差別。對(duì)于ARM2Linux可以找到如下部分:
# ifndef IN TPTR_ TYPE
# if SQL ITE_PTR_SZ = = 4
# define IN TPTR_ TYPE int
# else
# define IN TPTR_ TYPE long long
# endif
在上面的代碼前加上一句
# define SQL ITE_PTR_SZ 4
這樣后面的“typedef INTPTR_ TYPE pt r ;”就是定義的“int”類(lèi)型,而不是“l(fā)ong long”。
④準(zhǔn)備使用configure進(jìn)行一些配置。請(qǐng)?jiān)趕qlite目錄下的configure中找到如下4處,并將他們注釋掉,這樣可以讓configure不去檢查你的交叉編譯環(huán)境。
⑤修改Makefile文件。將代碼行BCC = arm linux gcc g O2 改成BCC = gcc g O2 。另外,一般是以靜態(tài)鏈接的形式將sqlite 放到ARM Linux 的硬件板上運(yùn)行的,所以繼續(xù)修改Makefile ,找到標(biāo)記為sqlite :的代碼段,將其中的libsqlite. la 改成. libs/ libsqlite. a 。做完上述修改,用make 生成sqlite 、libsqlite. a 、libsqlite. so 。為了減小執(zhí)行文件大小可以用st rip 處理,去掉其中的調(diào)試信息。
⑥在ARM 板上運(yùn)行sqlite。將sqlite 拷貝到ARM板上,方法很多,需要根據(jù)具體的情況來(lái)選擇。如ftp 、cm2 dftp 、wget 等。將sqlite下載到ARM 板的/ tmp 目錄,因?yàn)榇四夸浭强蓪?xiě)的。修改權(quán)限并運(yùn)行:
chmod + wx sqlite
. / sqlite test . sqlite
會(huì)出現(xiàn)
sqlite >
如果一切正常,現(xiàn)在sqlite已經(jīng)在ARM Linux下跑了起來(lái),然后就可以基于此進(jìn)行進(jìn)一步的應(yīng)用開(kāi)發(fā)了。
4 SQLite 在ARM- Linux 系統(tǒng)中應(yīng)用實(shí)例
在基于Linux的媒體網(wǎng)絡(luò)附屬存儲(chǔ)(media network attached storage,Media NAS)系統(tǒng)中,選用SQLite數(shù)據(jù)庫(kù)作為NAS系統(tǒng)中媒體數(shù)據(jù)的存儲(chǔ)數(shù)據(jù)庫(kù),使得數(shù)字媒體播放設(shè)備通過(guò)UPnP ( universal plug-and-play)協(xié)議對(duì)NAS上的媒體文件進(jìn)行播放。該系統(tǒng)中用戶瀏覽媒體文件的流程如下::
(1)當(dāng)用戶瀏覽NAS系統(tǒng)中的媒體文件時(shí),執(zhí)行DatabaseOpen數(shù)據(jù)庫(kù)打開(kāi)操作。
(2)接著查找當(dāng)前的SQLite數(shù)據(jù)庫(kù)表,得到媒體文件的路徑,通過(guò)DatabaseExecute執(zhí)行SQL 查詢語(yǔ)句得到路徑。
(3)通過(guò)媒體文件的路徑打開(kāi)媒體文件,把媒體文件,通過(guò)UPnP網(wǎng)絡(luò)發(fā)送出去。SQLite的特點(diǎn)決定了它與應(yīng)用結(jié)合時(shí)的便捷性。作為數(shù)據(jù)的存儲(chǔ)介質(zhì),SQLite文件被保存為一個(gè)普通的磁盤(pán)二進(jìn)制文件,它無(wú)需一個(gè)服務(wù)器進(jìn)程來(lái)提供服務(wù),對(duì)SQLite數(shù)據(jù)文件的直接操作即可完成想要做的工作。結(jié)合應(yīng)用需求,在應(yīng)用層編寫(xiě)了一組對(duì)SQLite的API調(diào)用操作的簡(jiǎn)單封裝,部分封裝函數(shù)如下::
DatabaseOpen ;調(diào)用SQLite_open打開(kāi)數(shù)據(jù)庫(kù)文件
DatabaseClose ;調(diào)用SQLite_close關(guān)閉數(shù)據(jù)庫(kù)
DatabaseExecute ;執(zhí)行SQL命令
應(yīng)用層的部分封裝函數(shù)的實(shí)現(xiàn)代碼如下::
int DatabaseOpen ( struct DBObj3 db, const char3 dbName)
{
char3 pzErrMsg = NULL;
structDB Info3 pDB info; / /數(shù)據(jù)庫(kù)文件指針
if (NULL = = dbName) return 1;
pDBinfo = ( struct DB Info3 ) db - > priv;
pDBinfo - > stConnect = ( struct sqlite3 ) sqlite_open ( dbName, 0777, &pzErrMsg) ;
if ( NULL = = pDB info - > stConnect )
{
printf ( " db open error. " ) ;
return 1;
}
return 0;
}
int DatabaseExecute ( struct DBObj3 db, const char3 szSQL)
{
char3 pErrMsg = NULL;
int nErrorCode;
struct DB Info3 pDBinfo;
pDB info = ( structDB Info3 ) db —> priv;
nErrorCode = sqlite_exec ( ( struct sqlite 3 )(pDBinfo - > stConnect) ,
szSQL, NULL, NULL, &pErrMsg) ;
return nErrorCode;
}
可以看出,各個(gè)封裝函數(shù)是通過(guò)調(diào)用SQLite的API函數(shù)實(shí)現(xiàn)的。在基于Linux操作系統(tǒng)上使用SQLite,經(jīng)測(cè)試嵌入式數(shù)據(jù)庫(kù)響應(yīng)迅速,運(yùn)行穩(wěn)定,用戶基本感覺(jué)不到命令延遲,在瀏覽聲音和圖像媒體時(shí)流暢自然,充分驗(yàn)證了使用SQLite數(shù)據(jù)庫(kù)的優(yōu)越性。
5 總結(jié)
在經(jīng)過(guò)大量的分析對(duì)比之后,針對(duì)嵌入式系統(tǒng)開(kāi)發(fā)的特點(diǎn),從眾多數(shù)據(jù)庫(kù)發(fā)行版中選出非常適用的嵌入式數(shù)據(jù)庫(kù)SQLite。ARM-Linux下完成了對(duì)SQLite的編譯,并基于此在項(xiàng)目中作了進(jìn)一步的開(kāi)發(fā)工作。實(shí)踐證明,SQLite能夠出色地完成嵌入式系統(tǒng)中的數(shù)據(jù)庫(kù)應(yīng)用需求。
參考文獻(xiàn)
[1] 譚愛(ài)國(guó),琚長(zhǎng)江,余 濤.SQLite在基于L inux的Media NAS系統(tǒng)中的應(yīng)用[J]。武漢理工大學(xué)學(xué)報(bào):信息與管理工程版, 2007, 29 (6)
[2] 曾立勝. 基于SQL ite嵌入式數(shù)據(jù)庫(kù)的射頻卡數(shù)據(jù)存儲(chǔ)[ J ]. 電腦知識(shí)與技術(shù), 2006 (8)
[3] 倪天龍,張賢高,王培.數(shù)據(jù)庫(kù)SQLite在嵌入式系統(tǒng)中的應(yīng)用[ J ]. 單片機(jī)與嵌入式系統(tǒng)應(yīng)用, 2005 (10) : 35 - 37.
[4] 萬(wàn)瑪寧. 嵌入式數(shù)據(jù)庫(kù)典型技術(shù)SQLite和Berkeley DB的研究[J]. 微計(jì)算機(jī)信息,2006/02
[5] 王冠宇. JAVA在SQLite嵌入式數(shù)據(jù)庫(kù)中的應(yīng)用[J]. 微計(jì)算機(jī)信息,2006/02