關於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常見問題集的內容介紹完了,希望通過本文的學習能對你有所協助!