解析SQLite中的常見問題與總結詳解

一、 建立數據
若是不往數據庫裏面添加任何的表,這個數據庫等於沒有創建,不會在硬盤上產生任何文件,若是數據庫已經存在,則會打開這個數據庫。

二、 如何經過sqlite3.dll與sqlite3.def生成sqlite3.lib文件
LIB /DEF:sqlite3.def /machine:IX86

三、 sqlite3_open打開一個數據庫時,若是數據庫不存在就會新生成一個數據庫文件。若是接着執行其餘查詢語句就會失敗,好比sqlite3_prepare,編程中出現明明指定了數據庫並且裏面也有數據,爲何查詢失敗了,主要是數據庫名路徑不對引發的。通常的作法是先檢查數據庫文件是否存在,若是存在就使用sqlite3_open打開數據庫;不然建立一個新的數據庫。

四、 如何創建自動增加字段
聲明爲INTEGER PRIMARY KEY的列將會自動增加。

五、SQLite3支持何種數據類型?
NULL
INTEGER
REAL
TEXT
BLOB
但實際上,sqlite3也接受以下的數據類型:
smallint 16位元的整數。
interger 32位元的整數。
decimal(p,s) p精確值和s大小的十進位整數,精確值p是指所有有幾個數(digits)大小值,s是指小數點後有幾位數。若是沒有特別指定,則系統會設爲p=5; s=0。
float 32位元的實數。
double 64位元的實數。
char(n) n長度的字串,n不能超過254。
varchar(n)長度不固定且其最大長度爲n的字串,n不能超過4000。
graphic(n)和char(n)同樣,不過其單位是兩個字元double-bytes,n不能超過127。這個形態是爲了支援兩個字元長度的字體,例如中文字。
vargraphic(n)可變長度且其最大長度爲n的雙字元字串,n不能超過2000。
date包含了年份、月份、日期。
time包含了小時、分鐘、秒。
timestamp包含了年、月、日、時、分、秒、千分之一秒。

六、SQLite容許向一個integer型字段中插入字符串
這 是一個特性,而不是一個bug。SQLite不強制數據類型約束。任何數據均可以插入任何列。你能夠向一個整型列中插入任意長度的字符串,向布爾型列中插 入浮點數,或者向字符型列中插入日期型值。在CREATE TABLE中所指定的數據類型不會限制在該列中插入任何數據。任何列都可接受任意長度的字符串(只有一種狀況除外:標誌爲INTEGER PRIMARY KEY的列只能存儲64位整數,當向這種列中插數據除整數之外的數據時,將會產生錯誤。

但SQLite確實使用聲明的列類型來指示你所指望的格式。因此,例如你向一個整型列中插入字符串時,SQLite會試圖將該字符串轉換成一個整數。若是能夠轉換,它將插入該整數;不然,將插入字符串。這種特性有時被稱爲類型或列親和性(type or column affinity).

七、爲何SQLite不容許在同一個表不一樣的兩行上使用0和0.0做主鍵?
主鍵必須是數值類型,將主鍵改成TEXT型將不起做用。
每一行必須有一個惟一的主鍵。對於一個數值型列,SQLite認爲'0'和'0.0'是相同的,由於他們在做爲整數比較時是相等的(參見上一問題)。因此,這樣值就不惟一了。

八、多個應用程序或一個應用程序的多個實例能夠同時訪問同一個數據庫文件嗎?
 
多個進程可同時打開同一個數據庫。多個進程能夠同時進行SELECT操做,但在任一時刻,只能有一個進程對數據庫進行更改。
 
SQLite使用讀、寫鎖控制對數據庫的訪問。(在Win95/98/ME等不支持讀、寫鎖的系統下,使用一個機率性的模擬來代替。)但使用時要注意:若是數據庫文件存放於一個NFS文件系統上,這種鎖機制可能不能正常工做。這 是由於fcntl()文件鎖在不少NFS上沒有正確的實現。在可能有多個進程同時訪問數據庫的時候,應該避免將數據庫文件放到NFS上。在Windows 上,Microsoft的文檔中說:若是使用FAT文件系統而沒有運行share.exe守護進程,那麼鎖多是不能正常使用的。那些在Windows上 有不少經驗的人告訴我:對於網絡文件,文件鎖的實現有好多Bug,是靠不住的。若是他們說的是對的,那麼在兩臺或多臺Windows機器間共享數據庫可能 會引發不指望的問題。

咱們意識到,沒有其它嵌入式的SQL數據庫引擎能象SQLite這樣處理如此多的併發。SQLite容許多個進程同時打開一個數據庫,同時讀一個數據庫。當有任何進程想要寫時,它必須在更新過程當中鎖住數據庫文件。但那一般只是幾毫秒的時間。其它進程只需等待寫進程幹完活結束。典型地,其它嵌入式的SQL數據庫引擎同時只容許一個進程鏈接到數據庫。

但 是,Client/Server數據庫引擎(如PostgreSQL, MySQL,或Oracle)一般支持更高級別的併發,而且容許多個進程同時寫同一個數據庫。這種機制在Client/Server結構的數據庫上是可能 的,由於老是有一個單一的服務器進程很好地控制、協調對數據庫的訪問。若是你的應用程序須要不少的併發,那麼你應該考慮使用一個 Client/Server結構的數據庫。但經驗代表,不少應用程序須要的併發,每每比其設計者所想象的少得多。

當SQLite試圖訪問一個被其它進程鎖住的文件時,缺省的行爲是返回SQLITE_BUSY。能夠在C代碼中使用sqlite3_busy_handler()sqlite3_busy_timeout() API函數調整這一行爲。

九、SQLite線程安全嗎?
線程是魔鬼(Threads are evil)。避免使用它們。
SQLite 是線程安全的。因爲不少用戶會忽略咱們在上一段中給出的建議,咱們作出了這種讓步。可是,爲了達到線程安全,SQLite在編譯時必須將 SQLITE_THREADSAFE預處理宏置爲1。在Windows和Linux上,已編譯的好的二進制發行版中都是這樣設置的。若是不肯定你所使用的 庫是不是線程安全的,能夠調用sqlite3_threadsafe()接口找出。

十、在SQLite數據庫中如何列出全部的表和索引?
若是你運行sqlite3命令行來訪問你的數據庫,能夠鍵入「.tables」來得到全部表的列表。或者,你能夠輸入「.schema」來看整個數據庫模式,包括全部的表的索引。輸入這些命令,後面跟一個LIKE模式匹配能夠限制顯示的表。

十一、SQLite數據庫有已知的大小限制嗎?
在Windows和Unix下,版本2.7.4的SQLite能夠達到2的41次方字節(2T字節)。老版本的爲2的31次方字節(2G字節)。
SQLite版本2.8限制一個記錄的容量爲1M。SQLite版本3.0則對單個記錄容量沒有限制。
表名、索引表名、視圖名、觸發器名和字段名沒有長度限制。但SQL函數的名稱(由sqlite3_create_function() API函數建立)不得超過255個字符。

十二、在SQLite中,VARCHAR字段最長是多少?
SQLite不強制VARCHAR的長度。你能夠在SQLITE中聲明一個VARCHAR(10),SQLite仍是能夠很高興地容許你放入500個字符。而且這500個字符是原封不動的,它永遠不會被截斷。
 
1三、在SQLite中,如何在一個表上添加或刪除一列?
SQLite有有限地ALTER TABLE支持。你可使用它來在表的末尾增長一列,可更改表的名稱。若是須要對錶結構作更復雜的改變,則必須從新建表。重建時能夠先將已存在的數據放到一個臨時表中,刪除原表,建立新表,而後將數據從臨時表中複製回來。

如,假設有一個t1表,其中有"a", "b", "c"三列,若是要刪除列c,如下過程描述如何作:

BEGIN TRANSACTION;
CREATE TEMPORARY TABLE t1_backup(a,b);
INSERT INTO t1_backup SELECT a,b FROM t1;
DROP TABLE t1;
CREATE TABLE t1(a,b);
INSERT INTO t1 SELECT a,b FROM t1_backup;
DROP TABLE t1_backup;
COMMIT;
1四、在SQLite中支持分頁嗎?
 
SQLite分頁是世界上最簡單的。若是我要去11-20的Account表的數據Select * From Account Limit 9 Offset 10;
以上語句表示從Account表獲取數據,跳過10行,取9行。這個特性足夠讓不少的web中型網站使用這個了。也能夠這樣寫 select * from account limit10,9和上面的的效果同樣。這種寫法MySQL也支持。git

相關文章
相關標籤/搜索