SQLite 實現與應用

2021-07-11 03:18:49 字數 3456 閱讀 2738

1、前言

有一些日子沒有仔細關注sqlite了,今天開啟其主頁,發現其最新的版本已經是3.6.22了,更讓我驚喜的是它的使用者越來越多,而且郵件列表的關注者也越來越多,突然覺得自己已經太old了。驚喜的同時,不得不聊上幾句了。

firefox:這是我的機器上v3.5.7安裝目錄下的檔案:

可以發現用的sqlite 3.6.16.1。

2、實現與應用

下面從實現及應用的角度來談談sqlite,先看看sqlite的特點(功能)吧。特點

簡單(******):sqlite是乙個非常輕量級自包含(lightweight and self-contained)的dbms:乙個標頭檔案,乙個動態庫檔案,你就擁有了關聯式資料庫的所有功能了。簡單,是sqlite最明顯的哲學。它提供的api少而簡單。只需要乙個dll檔案,你的程式馬上就擁有了乙個功能強大的資料庫引擎,這是一件很美妙的事。

小巧(small):我用vs 2005在windows下編譯的3.6.11,release版為368k,用時不到20秒——而編譯mysql時,要花上幾分鐘。而當我插入10000條int資料時,記憶體開銷660k,磁碟開銷92k。

事務(transaction):事務是現代商業資料處理系統最基本的要求,而access,不論是在可執行檔案大小(看了一下access2003的可執行檔案大小為6.32m,兩者不是乙個量級),還是事務特性,都是不能和sqlite 相比的。

併發性(concurrency):由於sqlite通過os的檔案鎖來實現庫級鎖,粒度很大,但是,它通過一些複雜特殊的處理(具體可以參見分析系列),盡量的提公升了讀寫的併發度。如果你還有擔心,你可以看看這篇文章:

sql92:sqlite支援絕大部分的標準sql語句,你只需要幾百k的空間,就可以換來需要上百兆的通用dbms幾乎所有操作了。

方便(convenience):如果你的程式要使用sqlite,只需要將拷貝你的程式目錄即可。

開源(opensource):這是它最強大的地方。開源,意味著你可以品讀它的原始碼,你可以隨時修改它,加入你自己的特性,而這一切完全免費的。開源,是一種精神。

實現部分

好了,現在從實現的角度來談談個人體會,這也是我比較關注的。

sqlite是一款優秀的嵌入式資料庫管理系統,這裡有兩層含義:一是它經常作為動態庫嵌入到應用程式;另外一方面它通常用於嵌入式裝置或其它要求較低的桌面應用。如果把它作為記憶體資料庫,個人覺得不是很適合。畢竟,它的寫併發性不是很好,此時, timesten也許會更好,berkey db也許是乙個不錯的選擇。sqlite這樣的嵌入式資料庫與主存資料庫的應用場景、實現以及對資源的需求都是不一樣的。

(1)事務處理

事務的核心問題有兩個:併發控制和恢復。解決了併發控制和恢復問題的系統,就能允許它的使用者假設程式是原子的(atomically)執行的——好像沒有其它的程式同時執行;而且是可靠的(reliably)——不會產生失敗。原子性和可靠性的抽象,則稱為事務(transaction)。其實,事務並不是dbms的專利,任何分布式系統,都面對併發和恢復問題,而解決的方法就是事務,只不過,我們更常聽到dbms中的事務。

併發控制保證事務的原子執行,它使得交錯執行的事務看起來是乙個接乙個的順序執行的,完全沒有交錯執行。如果交錯執行的結果與順序執行的結果一致,則稱為序列化(serializable)。

恢復使得資料庫僅僅包含那些正常完成的事務的結果。如果事務在執行的過程中發生錯誤,不能繼續進行,恢復演算法必須清除部分完成事務產生的影響。

sqlite只支援庫級鎖,庫級鎖意味著什麼?——意味著同時只能允許乙個寫操作,也就是說,即事務t1在a表插入一條資料,事務t2在b表中插入一條資料,這兩個操作不能同時進行,即使你的機器有100個cpu,也無法同時進行,而只能順序進行。表級都不能並行,更別說元組級了——這就是庫級鎖。但是,sqlite盡量延遲申請x鎖,直到資料塊真正寫盤時才申請x鎖,這是非常巧妙而有效的。

sqlite的恢復技術是影子分頁技術(shadow paging)技術的典型代表。

dbms的常用恢復技術有影子分頁技術與基於日誌的技術,前者在早其資料庫管理系統中用到,比如system r,現代dbms中已經很難見到它的身影了。

影子分頁技術與基於日誌技術相比,優點是實現簡單,消除了寫日誌記錄的開銷,恢復的速度也快(不需要redo和undo)。影子分頁的缺點就是事務提交時要輸出多個塊,這使得提交的開銷很大,而且以塊為單位,很難應用到允許多個事務併發執行的情況——這是它致命的缺點。

(2)查詢處理

sqlite的查詢處理本質上就是乙個sql編譯器和乙個虛擬機器。而實現這些功能只用了十多個檔案,整個實現實現簡單而有效,但是也存在一些問題。首先,sqlite字典資料很簡單,實際上它的字典就乙個表sqlite_mater,所有的資訊都是通過對sqlite_master中sql語句進行解析獲取的,而解析乙個sql語句,都需要進行詞法分析、語法分析、甚至虛擬機器**的生成。而這一過程是很需要時間的,而且,查詢計畫也沒有重用。其次,查詢優化還比較簡單,特別是連線操作,只通過迴圈來做(mysql也一樣)。但是,僅僅數萬**,我們不能對它要求太苛求。

(3)儲存模型

sqlite的檔案物理上被劃分成相同大小的塊;邏輯上劃分成一些b-tree——每個表對應乙個b-tree。而沒有像oracle,或者innodb對資料塊進行複雜的邏輯組織,這種按需分配資料塊的做法必然影響磁碟的讀寫效能。不過,歸根到底,還是源於它的應用場景。

(4)緩衝區管理

buffer的管理對於dbms,無疑是非常重要的,sqlite在其它方面做得比較簡單,但是在緩衝區管理這一塊,它還是做足了功夫。sqlite採用dbms常用的lru演算法。更值得一提的是,在較新的版本中,sqlite採用和虛擬檔案系統的類似的方式,實現了讓預設緩衝區管理子系統可以很容易的切換成其它的緩衝區管理演算法,這是非常靈活的。

(5)i/o

sqlite採用簡單的阻塞i/o,較新的版本將非同步i/o作為可選的擴充套件,但是,由於sqlite沒有日誌,所以,事務中acid中的d,就無法保證,所以,如果你的資料很關鍵,請不要用sqlite的非同步i/o。另一方面,實際上,很多嵌入式作業系統,比如windows ce並不支援非同步i/o(不過,這可以通過多執行緒加以解決)。

但是,這些「缺點」並不是sqlite的缺點,相對於通過dbms,恰恰是它的優點,這樣的實現簡單,而且對資源的需求較低。對嵌入式裝置、或者那些要求較低的應用,已經足夠,足夠就好。

應用場景

嵌入式裝置:這應該是sqlite應用的主要場景,很多公司都在他們的嵌入式應用程式中使用sqlite,其中不乏google的android。

桌面應用:如果你已經厭惡了fopen,fread,fwrite這些函式,sqlite是你不錯的選擇,它介面簡單,而且支援事務。前些天無意中下了乙個cookie清除軟體——cookiecrumbler,開啟一看,發現裡面竟然有乙個sqlite3.dll,著實讓我震驚了一把。

websites:如果你的站點的訪問量、資料量小的個人站點,sqlite可以代替開銷較大的mysql和繁雜的access。後記

sqlite正在不斷發展,開源的力量是巨大的,相信它的應用會越來越廣泛。wish~

Sqlite入門與C C 的應用

下面這個程式是我寫的乙個例子,具有基本功能,但可能方法不是很好。include sqlite3.h include include pragma comment lib,sqllib.lib int select callback void data,int col count,char col v...

SQLite函式應用(一)

開啟資料庫 sqlite3 open int sqlite3 open const char filename,database filename utf 8 sqlite3 ppdb out sqlite db handle filename引數是檔名,或字串 memory 或乙個空指標 null...

SQLite函式應用(二)

callback函式 sqlite3 db int rc char zerr rc sqlite3 open test.db,db if rc cout error char data callback char sql select from test rc sqlite3 exec db,sql...