sqlite3使用範圍
SQLite不同於其他大部分的SQL數據庫引擎,因爲它的首要設計目標就是簡單化: 1.易於管理 2.易於使用 3.易於嵌入其他大型程序 4.易於維護和配置
許多人喜歡SQLite因爲它的小巧和快速. 但是這些特性只是它的部分優點, 使用者還會發現SQLite是非常穩定的. 出色的穩定性源於它的簡單, 越簡單就越不容易出錯. 除了上述的簡單、小巧和穩定性外, 最重要的在於SQLite力爭做到簡單化.
簡單化在一個數據庫引擎中可以說是一個優點, 但也可能是個缺點, 主要決定於你想要做什麼. 爲了達到簡單化, SQLite省略了一些人們認爲比較有用的特性, 例如高併發性、嚴格的存取控制、豐富的內置功能、存儲過程、複雜的SQL語言特性、 XML以及Java的擴展, 超大的萬億級別的數據測量等等. 如果你需要使用上述的這些特性並且不介意它們的複雜性, 那麼SQLite也許就不適合你了. SQLite沒有打算作爲一個企業級的數據庫引擎, 也並不打算和Oracle或者PostgreSQL競爭.
僅憑經驗來說SQLite適用於以下場合: 當你更看中簡單的管理、使用和維護數據庫, 而不是那些企業級數據庫提供的不計其數的複雜功能的時候,使用SQLite是一個比較明智的選擇. 事實也證明, 人們在許多情況下已經清楚的認識到簡單就是最好的選擇.
SQLite最佳試用場合
- 網站:作爲數據庫引擎SQLite適用於中小規模流量的網站(也就是說, 99.9%的網站). SQLite可以處理多少網站流量在於網站的數據庫有多大的壓力. 通常來說, 如果一個網站的點擊率少於100000次/天的話, SQLite是可以正常運行的. 100000次/天是一個保守的估計, 不是一個準確的上限. 事實證明, 即使是10倍的上述流量的情況下SQLite依然可以正常運行.
- 嵌入式設備和應用軟件:因爲SQLite數據庫幾乎不需要管理, 因此對於那些無人值守運行或無人工技術支持的設備或服務, SQLite是一個很好的選擇. SQLite能很好的適用於手機, PDA, 機頂盒, 以及其他儀器. 作爲一個嵌入式數據庫它也能夠很好的應用於客戶端程序.
- 應用程序文件格式:SQLite作爲桌面應用程序的本地磁盤文件格式取得了巨大成功.例如金融分析工具、CAD 包、檔案管理程序等等. 一般的數據庫打開操作需要調用sqlite3_open()函數,並且標記一個顯式本地事務的起始點(BEGIN TRANSACTION)來保證以獨佔的方式得到文件的內容. 文件保存將執行一個提交(COMMIT)同時標記另一個顯式本地事務起始點. 這種事務處理的作用就是保證對於應用程序數據文件的更新是原子的、持久的、獨立的和一致的. 數據庫裏可以加入一些臨時的觸發器,用來把所有的改變記錄在一張臨時的取消/重做日誌表中. 當用戶按下取消/重做按鈕的時候這些改變將可以被回滾. 應用這項技術實現一個無限級的取消/重做功能只需要編寫很少的代碼.
- 替代某些特別的文件格式:許多程序使用fopen(), fread(), 或 fwrite()函數創建和管理一些自定義的文件用來保存數據. 使用SQLite替代這些自定義的文件格式將是一種很好的選擇.
- 內部的或臨時的數據庫:對於那些有大量的數據需要用不同的方式篩選分類的程序, 相對於編寫同樣功能的代碼, 如果你把數據讀入一個內存中的SQLite數據庫, 然後使用連接查詢和ORDER BY子句按一定的順序和排列提取需要的數據, 通常會更簡單和快速. 按照上述的方法使用內嵌的SQLite數據庫將會使程序更富有靈活性, 因爲添加新的列或索引不用重寫任何查詢語句.
- 命令行數據集分析工具:有經驗的SQL用戶可以使用SQLite命令行程序去分析各種混雜的數據集. 原是數據可以從CSV(逗號分隔值文件)文件中導入, 然後被切分產生無數的綜合數據報告. 可能得用法包括網站日誌分析, 運動統計分析, 編輯規劃標準, 分析試驗結果. 當然你也可以用企業級的客戶端/服務器數據庫來做同樣的事情. 在這種情況下使用SQLite的好處是: SQLite的部署更爲簡單並且結果數據庫是一個單獨的文件, 你可以把它存儲在軟盤或者優盤或者直接通過email發給同事.
- 在Demo或測試版的時候作爲企業級數據庫的替代品:如果你正在編寫一個使用企業級數據庫引擎的客戶端程序, 使用一個允許你連接不同SQL數據庫引擎的通用型數據庫後臺將是很有意義的. 其更大的意義在於將SQLite數據庫引擎靜態的連接到客戶端程序當中,從而內嵌SQLite作爲混合的數據庫支持. 這樣客戶端程序就可以使用SQLite數據庫文件做獨立的測試或者驗證.
- 數據庫教學:因爲SQLite的安裝和使用非常的簡單(安裝過程幾乎忽略不計, 只需要拷貝SQLite源代碼或sqlite.exe可執行文件到目標主機, 然後直接運行就可以) 所以它非常適合用來講解SQL語句. 同學們可以非常簡單的創建他們喜歡的數據庫, 然後通過電子郵件發給老師批註或打分. 對於那些感興趣怎樣實現一個關係型數據庫管理系統(RDBMS)的高層次的學生, 按照模塊化設計且擁有很好的註釋和文檔的SQLite源代碼, 將爲他們打下良好的基礎. 這並不是說SQLite就是如何實現其他數據庫引擎的精確模型, 但是很適合學生們瞭解SQLite是如何快速工作的, 從而掌握其他數據庫系統的設計實現原則.
- 試驗SQL語言的擴展:SQLite簡單且模塊化的設計使得它可以成爲一個用來測試數據庫語言特性或新想法的優秀的原型平臺.
sqlite3基礎
SQLite的源代碼是C,其源代碼完全開放。SQLite第一個Alpha版本誕生於2000年5月。 他是一個輕量級的嵌入式數據庫。
目標:易於管理、操作、維護、自定義以及提供易用的編程接口
SQLite有以下特性(優點)
- 零配置一無需安裝和管理配置;
- 儲存在單一磁盤文件中的一個完整的數據庫;
- 數據庫文件可以在不同字節順序的機器間自由共享;
- 支持最大 2tb 的單個庫文件;
- 足夠小,全部源碼大致3萬行c代碼,250KB;
- 比目前流行的大多數數據庫對數據的操作要快;比MySQL(2倍), PostgreSQL(20倍)快
- 允許爲SQL命令集動態添加自定義函數(簡單函數及聚集函數),而無需重編SQLite庫
- ACID兼容(原子性,一致性,獨立性,可持久性,Atomicity、Consistency、Isolation、Durability ),支持視圖,子查詢,觸發器
SQLite的缺點
- 事務處理併發性:SQLite通過數據庫級上的獨佔性和共享鎖來實現獨立事務處理,這意味着當多個進程或線程在同一時間可以從數據庫讀取數據,但是只能有一個可以同時寫入,在寫入之前,必須獲得獨佔鎖,其它的讀操作不允許發生。
- 性能:在創建索引( CREATE INDEX)和刪除表( DELTE TABLE)時明顯比其它數據庫慢
- 用戶管理/安全:數據庫的訪問是基於操作系統對文件的控制來控制的,不能通過用戶來區分數據庫中的不同數據庫。舉例,將數據庫文件去寫權限,然後向其中插入或刪除數據條目,將提示寫失敗。但是不能通過數據庫本身的來對權限進行設置。
SQLite的內部結構
在內部,SQLite 由以下幾個組件組成:SQL 編譯器、內核、後端以及附件。SQLite 通過利用虛擬機和虛擬數據庫引擎(VDBE),使調試、修改和擴展 SQLite 的內核變得更加方便。所有 SQL 語句都被編譯成易讀的、可以在 SQLite 虛擬機中執行的程序集。
1.接口將SQL語句傳給SQL編譯器
2.SQL編譯器選將SQL分解成爲Token
3.將Token傳遞給解析器進行解析
4.由代碼生成器生成虛擬機代碼
5.由虛擬機執行生成的程序
6.SQLite庫在磁盤上以B樹形式組織(每個表和索引都有自己單獨的B樹,所有的B樹都保存的同一個文件裏面)
7.OS層的操作
製作一個靜態的sqlite3.lib文件
生成動態的sqlite3.lib,與sqlite3.dll一起使用
由源碼來製作sqlite.dll文件
- 錯誤 8 error LNK2001: 無法解析的外部符號 sqlite3_table_column_metadata E:\workPlace\VS2010Project\MFCDLL\sqlite3\sqlite3.def 1 sqlite3
- 錯誤 7 error LNK2001: 無法解析的外部符號 sqlite3_column_table_name16 E:\workPlace\VS2010Project\MFCDLL\sqlite3\sqlite3.def 1 sqlite3
- 錯誤 6 error LNK2001: 無法解析的外部符號 sqlite3_column_table_name E:\workPlace\VS2010Project\MFCDLL\sqlite3\sqlite3.def 1 sqlite3
- 錯誤 5 error LNK2001: 無法解析的外部符號 sqlite3_column_origin_name16 E:\workPlace\VS2010Project\MFCDLL\sqlite3\sqlite3.def 1 sqlite3
- 錯誤 4 error LNK2001: 無法解析的外部符號 sqlite3_column_origin_name E:\workPlace\VS2010Project\MFCDLL\sqlite3\sqlite3.def 1 sqlite3
- 錯誤 3 error LNK2001: 無法解析的外部符號 sqlite3_column_database_name16 E:\workPlace\VS2010Project\MFCDLL\sqlite3\sqlite3.def 1 sqlite3
- 錯誤 2 error LNK2001: 無法解析的外部符號 sqlite3_column_database_name E:\workPlace\VS2010Project\MFCDLL\sqlite3\sqlite3.def 1 sqlite3
錯誤 8 error LNK2001: 無法解析的外部符號 sqlite3_table_column_metadata E:\workPlace\VS2010Project\MFCDLL\sqlite3\sqlite3.def 1 sqlite3
錯誤 7 error LNK2001: 無法解析的外部符號 sqlite3_column_table_name16 E:\workPlace\VS2010Project\MFCDLL\sqlite3\sqlite3.def 1 sqlite3
錯誤 6 error LNK2001: 無法解析的外部符號 sqlite3_column_table_name E:\workPlace\VS2010Project\MFCDLL\sqlite3\sqlite3.def 1 sqlite3
錯誤 5 error LNK2001: 無法解析的外部符號 sqlite3_column_origin_name16 E:\workPlace\VS2010Project\MFCDLL\sqlite3\sqlite3.def 1 sqlite3
錯誤 4 error LNK2001: 無法解析的外部符號 sqlite3_column_origin_name E:\workPlace\VS2010Project\MFCDLL\sqlite3\sqlite3.def 1 sqlite3
錯誤 3 error LNK2001: 無法解析的外部符號 sqlite3_column_database_name16 E:\workPlace\VS2010Project\MFCDLL\sqlite3\sqlite3.def 1 sqlite3
錯誤 2 error LNK2001: 無法解析的外部符號 sqlite3_column_database_name E:\workPlace\VS2010Project\MFCDLL\sqlite3\sqlite3.def 1 sqlite3
4.解決辦法,在sqlite.c文件中,頂部添加- #ifndef SQLITE_ENABLE_COLUMN_METADATA
- # define SQLITE_ENABLE_COLUMN_METADATA
- #endif
#ifndef SQLITE_ENABLE_COLUMN_METADATA
# define SQLITE_ENABLE_COLUMN_METADATA
#endif
然後,在編譯,會生成sqlite.lib(48k)和sqlite.dll(debug版本780多k,release版本,500多k),使用DLL Export Viewer工具打開sqlite3.dll文件會看到有207個函數。- #ifndef SQLITE_HAS_CODEC
- # define SQLITE_HAS_CODEC
- #endif
#ifndef SQLITE_HAS_CODEC
# define SQLITE_HAS_CODEC
#endif
定義該宏之後,重新編譯代碼,發現現在編譯不通過了,提示有5個函數並沒有實現,它們分別是: --------這些實現可以在網上找到。- int sqlite3CodecAttach(sqlite3 * db, int nDB, const void * pKey, int nKeyLen)
- void sqlite3CodecGetKey(sqlite3 * db, int nDB, void ** Key, int * nKey)
- int sqlite3_key(sqlite3 * db, const void * pKey, int nKey)
- int sqlite3_rekey(sqlite3 * db, const void * pKey, int nKey)
- void sqlite3_activate_see(const char * right)
int sqlite3CodecAttach(sqlite3 * db, int nDB, const void * pKey, int nKeyLen)
void sqlite3CodecGetKey(sqlite3 * db, int nDB, void ** Key, int * nKey)
int sqlite3_key(sqlite3 * db, const void * pKey, int nKey)
int sqlite3_rekey(sqlite3 * db, const void * pKey, int nKey)
void sqlite3_activate_see(const char * right)