關于SQLite常見問題解答
關于SQLite常見問題解答是本文要介紹的內容,主要是我們在學習SQLite的時候遇到的一些問題,如何來解決呢,我們一起來看內容。
1、如何建立自動增長字段?
2、SQLite支持何種數據類型?
3、SQLite允許向一個integer型字段中插入字符串!
4、為什么SQLite不允許在同一個表不同的兩行上使用0和0.0作主鍵?
5、多個應用程序或一個應用程序的多個實例可以同時訪問同一個數據庫文件嗎?
(1) 如何建立自動增長字段?
簡短回答:聲明為 INTEGER PRIMARY KEY 的列將會自動增長。
長一點的答案: 如果你聲明表的一列為 INTEGER PRIMARY KEY,那么, 每當你在該列上插入一NULL值時, NULL自動被轉換為一個比該列中***值大1的一個整數,如果表是空的, 將會是1。 (如果是***可能的主鍵 9223372036854775807,那個,將鍵值將是隨機未使用的數。) 如,有下列表:
- CREATE TABLE t1( a INTEGER PRIMARY KEY, b INTEGER );
在該表上,下列語句
- INSERT INTO t1 VALUES(NULL,123);
在邏輯上等價于:
- INSERT INTO t1 VALUES((SELECT max(a) FROM t1)+1,123);
有一個新的API叫做 sqlite3_last_insert_rowid(),它將返回最近插入的整數值。
注意該整數會比表中該列上的插入之前的***值大1。 該鍵值在當前的表中是唯一的。但有可能與已從表中刪除的值重疊。要想建立在整個表的生命周期中唯一的鍵值,需要在 INTEGER PRIMARY KEY 上增加AUTOINCREMENT聲明。那么,新的鍵值將會比該表中曾能存在過的***值大1。如果***可能的整數值在數據表中曾經存在過,INSERT將會失敗, 并返回SQLITE_FULL錯誤代碼。
(2)SQLite支持何種數據類型?參見 http://www.sqlite.org/datatype3.html.
(3)SQLite允許向一個integer型字段中插入字符串!
這是一個特性,而不是一個bug。SQLite不強制數據類型約束。任何數據都可以插入任何列。你可以向一個整型列中插入任意長度的字符串, 向布爾型列中插入浮點數,或者向字符型列中插入日期型值。 在 CREATE TABLE 中所指定的數據類型不會限制在該列中插入任何數據。 任何列均可接受任意長度的字符串(只有一種情況除外:標志為INTEGER PRIMARY KEY的列只能存儲64位整數, 當向這種列中插數據除整數以外的數據時,將會產生錯誤。
但SQLite確實使用聲明的列類型來指示你所期望的格式。所以,例如你向一個整型列中插入字符串時,SQLite會試圖將該字符串轉換成一個整數。 如果可以轉換,它將插入該整數;否則,將插入字符串。這種特性有時被稱為 類型或列親和性(type or column affinity).
(4)為什么SQLite不允許在同一個表不同的兩行上使用0和0.0作主鍵?
主鍵必須是數值類型,將主鍵改為TEXT型將不起作用。
每一行必須有一個唯一的主鍵。對于一個數值型列, SQLite認為 '0' 和 '0.0' 是相同的,因為他們在作為整數比較時是相等的(參見上一問題)。 所以,這樣值就不唯一了。
(5)多個應用程序或一個應用程序的多個實例可以同時訪問同一個數據庫文件嗎?
多個進程可同時打開同一個數據庫。多個進程可以同時進行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代碼中使用 sqlite 3_busy_handler() 或 sqlite 3_busy_timeout() API 函數調整這一行為。
小結:關于SQLite常見問題解答的內容介紹完了,希望通過本文的學習能對你有所幫助!