愛悠閑 > SQLite 數據庫使用

SQLite 數據庫使用

分類: 經驗總結  |  作者: sky_qing 相關  |  發布日期 : 2014-05-12  |  熱度 : 1171°
SQLite 數據庫使用

一、SQLite 數據庫的安裝(sqlite-3.5.6,Ubuntu)
1. wget 鏈接地址
2. tar -xzvf sqlite-3.5.6.tar.gz
3. cd sqlite-3.5.6
4. ./configure
5. make
6. make install

測試安裝是否成功:
# ./sqlite3 text.db

如果安裝成功,會出現下面這樣的信息

SQLite version 3.5.6
Enter ".help" for instructions
sqlite

二、SQLite 數據庫介紹
SQLite 是目前最流行的開源嵌入式數據庫,和很多其他嵌入式存儲引擎相比(NoSQL),如 BerkeleyDB、MemBASE 等,SQLite 可以很好的支持關系型數據庫所具備的一些基本特征,如標準 SQL 語法、實務、數據表和索引等。事實上,盡管 SQLite 擁有諸多關系型數據庫的基本特征,然而由于應用場景的不同,它們之間并沒有更多的可比性。下面是 SQLite 的主要特征:
    1). 管理簡單,甚至可以認為無需管理。
    2). 操作方便,SQLite 生成的數據庫文件可以在各個平臺無縫移植。
    3). 可以非常方便的以多種形式嵌入到其他應用程序中,如靜態庫、動態庫等。
    4). 易于維護。
綜上所述,SQLite 的主要優勢在與靈巧、快速和可靠性高。SQLite 的設計者為了達到這一目標,在功能上作出了很關鍵性的取舍,與此同時,也失去了一些對 RDBMS 關鍵性功能的支持,如高并發、細粒度訪問控制(如行級鎖)、豐富的內置函數、存儲過程和復雜的 SQL 語句等。正式因為這些功能的犧牲才換來了簡單,而簡單又換來了高效性和高可靠性。

三、SQLite 數據庫核心對象和接口
1. 核心對象:
在 SQLite 中最主要的兩個對象是,database_connection 和 prepared_statement。database_connection 對象是由sqlite3_open() 接口函數創建并返回的,在應用程序使用任何其他 SQLite 接口函數之前,必須先調用該函數以便獲得 database_connnection 對象,在隨后的其他 APIs 調用中,都需要該對象作為輸入參數以完成相應的工作。至于 prepare_statement,我們可以簡單的將它視為編譯后的 SQL 語句,因此,所有和 SQL 語句執行相關的函數也都需要該對象作為輸入參數以完成指定的 SQL 操作。

2. 核心接口:
    1). sqlite3_open
    上面已經提到過這個函數了,它是操作 SQLite 數據庫的入口函數。該函數返回的 database_connection 對象是很多其他 SQLite APIs 的句柄參數。注意,我們通過該函數既可以打開已經存在的數據庫文件,也可以創建新的數據庫文件。對于該函數返回的 database_connection 對象,我們可以在多個線程之間共享該對象的指針,以便完成和數據庫相關的任意操作。然而在多線程情況下,我們更為推薦的使用方式是,為每個線程創建獨立的 database_connection 對象。對于該函數還有一點也需要額外說明,我們沒有必要為了訪問多個數據庫而創建多個數據庫連接對象,因為通過 SQLite 自帶的 ATTACH 命令可以在一個連接中方便的訪問多個數據庫。

    2). sqlite3_prepare
    該函數將 SQL 文本轉換為 prepared_statement 對象,并在函數執行后返回該對象的指針。事實上,該函數并不會評估參數指定 SQL 語句,它僅僅是將 SQL 文本初始化為待執行的狀態。最后需要指出的,對于新的應用程序我們可以使用sqlite3_prepare_v2 接口函數來替代該函數以完成相同的工作。

    3). sqlite3_step
    該函數用于評估 sqlite3_prepare 函數返回的 prepared_statement 對象,在執行完該函數之后,prepared_statement 對象的內部指針將指向其返回的結果集的第一行。如果打算進一步迭代其后的數據行,就需要不斷的調用該函數,直到所有的數據行都遍歷完畢。然而對于 INSERT、UPDATE 和 DELETE 等 DML 語句,該函數執行一次即可完成。

    4). sqlite3_column
    該函數用于獲取當前行指定列的數據,然而嚴格意義上講,此函數在 SQLite 的接口函數中并不存在,而是由一組相關的接口函數來完成該功能,其中每個函數都返回不同類型的數據,如:
    sqlite3_column_blob
    sqlite3_column_bytes
    sqlite3_column_bytes16
    sqlite3_column_double
    sqlite3_column_int
    sqlite3_column_int64
    sqlite3_column_text
    sqlite3_column_text16
    sqlite3_column_type
    sqlite3_column_value
    sqlite3_column_count
    其中 sqlite3_column_count 函數用于獲取當前結果集中的字段數據。下面是使用 sqlite3_step 和 sqlite3_column 函數迭代結果集中每行數據的偽代碼,注意這里作為示例代碼簡化了對字段類型的判斷:

int fieldCount = sqlite3_column_count(...);
while (sqlite3_step(...) <> EOF) 
{
    for (int i = 0; i < fieldCount; ++i) 
    {
        int v = sqlite3_column_int(...,i);
    }
}

    5). sqlite3_finalize
    該函數用于銷毀 prepared statement 對象,否則將會造成內存泄露。

     6). sqlite3_close
    該函數用于關閉之前打開的 database_connection 對象,其中所有和該對象相關的 prepared_statements 對象都必須在此之前先被銷毀。

3.執行 Query:
    函數 sqlite3_exec() 提供了一種 SQL 命令的快速、簡單的方法,它特別適合處理對數據庫的修改操作(不需要返回數據),如:INSERT、UPDATE 和 DELETE。

    int sqlite3_exec(sqlite3*, const char *sql, sqlite3_callback, void *, char **errmsg ); 

    第 1 個參數不再說了,是前面 open 函數得到的指針。說了是關鍵數據結構。 
    第 2 個參數 const char *sql 是一條 sql 語句,以 /0 結尾。 
    第 3 個參數 sqlite3_callback 是回調,當這條語句執行之后,sqlite3 會去調用你提供的這個函數。
    第 4 個參數 void * 是你所提供的指針,你可以傳遞任何一個指針參數到這里,這個參數最終會傳到回調函數里面,如果不需要傳遞指針給回調函數,可以填 NULL。
    第 5 個參數 char ** errmsg 是錯誤信息,注意是指針的指針,sqlite3 里面有很多固定的錯誤信息。執行 sqlite3_exec 之后,執行失敗時可以查閱這個指針(直接 printf(“%s/n”,errmsg))得到一串字符串信息,這串信息告訴你錯在什么地方。sqlite3_exec 函數通過修改你傳入的指針的指針,把你提供的指針指向錯誤提示信息,這樣 sqlite3_exec 函數外面就可以通過這個 char* 得到具體錯誤提示。
    說明:通常,sqlite3_callback 和它后面的 void * 這兩個位置都可以填 NULL。填 NULL 表示你不需要回調。比如你做 insert 操作,做 delete 操作,就沒有必要使用回調。而當你做 select 時,就要使用回調,因為 sqlite3 把數據查出來,得通過回調告訴你查出了什么數據。 

sqlite3_exec() 的回調函數:
typedef int (*sqlite3_callback)(  
    void*, /* Data provided in the 4th argument of sqlite3_exec() */  
    int, /* The number of columns in row */  
    char**, /* An array of strings representing fields in the row */  ---- 字段值
    char** /* An array of strings representing column names */        ---- 字段名

);



之前參考過網上幾篇不錯的文章,但是現在沒記起來是哪些,也沒去翻了,請見諒。


鏈接地址這是 SQLite 學習的一個不錯的網站,里面還有實例。


sqlite可以在shell底下直接執行命令:
sqlite3 film.db "select * from film;"
輸出 HTML 表格:
sqlite3 -html film.db "select * from film;"
將數據庫「倒出來」:
sqlite3 film.db ".dump" > output.sql
利用輸出的資料,建立一個一模一樣的數據庫(加上以上指令,就
在 sqlite 中運行 .sql 腳本:sqlite3 test.db < /var/waf/rules.sql

如果向sqlite3數據庫中插入大量數據,速度會比較慢,這個時候可以進行優化,方式有兩種:
1. 使用事務:(sql腳本)
BEGIN TRANSACTION;
INSERT INTO "rules" VALUES(1,..);
INSERT INTO "rules" VALUES(2,..);
........
INSERT INTO "rules" VALUES(1000000, ..);
COMMIT TRANSACTION;

2. 設置 synchronous 標志:
PRAGMA synchronous = OFF;         (放在sql文件的頭部)

如果是python,使用事務就很簡單了,只要在最后加上 conn.commit() 即可。如果直接在shell下運行,就用begin;commit; 即可。 

注意:

1. sqlite3_exec函數如果有返回錯誤信息,也就是第5個參數返回不為空,那就需要調用sqlite3_free函數去釋放第5個參數的指針。

2. sqlite3_mprintf函數拼接完sql語句后也需要調用sqlite3_free函數去釋放保存sql語句的空間。

3. sqlite3_column_text函數從數據庫中獲取字符串字段后,不需要調用sqlite3_free函數去釋放保存字符串的空間,這塊內存由sqlite3自己釋放。

參考:

鏈接地址

鏈接地址

鏈接地址



快乐彩中奖说明