關(guān)于SQLite常見問題解答
關(guān)于SQLite常見問題解答是本文要介紹的內(nèi)容,主要是我們在學(xué)習(xí)SQLite的時(shí)候遇到的一些問題,如何來解決呢,我們一起來看內(nèi)容。
1、如何建立自動增長字段?
2、SQLite支持何種數(shù)據(jù)類型?
3、SQLite允許向一個(gè)integer型字段中插入字符串!
4、為什么SQLite不允許在同一個(gè)表不同的兩行上使用0和0.0作主鍵?
5、多個(gè)應(yīng)用程序或一個(gè)應(yīng)用程序的多個(gè)實(shí)例可以同時(shí)訪問同一個(gè)數(shù)據(jù)庫文件嗎?
(1) 如何建立自動增長字段?
簡短回答:聲明為 INTEGER PRIMARY KEY 的列將會自動增長。
長一點(diǎn)的答案: 如果你聲明表的一列為 INTEGER PRIMARY KEY,那么, 每當(dāng)你在該列上插入一NULL值時(shí), NULL自動被轉(zhuǎn)換為一個(gè)比該列中***值大1的一個(gè)整數(shù),如果表是空的, 將會是1。 (如果是***可能的主鍵 9223372036854775807,那個(gè),將鍵值將是隨機(jī)未使用的數(shù)。) 如,有下列表:
- CREATE TABLE t1( a INTEGER PRIMARY KEY, b INTEGER );
在該表上,下列語句
- INSERT INTO t1 VALUES(NULL,123);
在邏輯上等價(jià)于:
- INSERT INTO t1 VALUES((SELECT max(a) FROM t1)+1,123);
有一個(gè)新的API叫做 sqlite3_last_insert_rowid(),它將返回最近插入的整數(shù)值。
注意該整數(shù)會比表中該列上的插入之前的***值大1。 該鍵值在當(dāng)前的表中是唯一的。但有可能與已從表中刪除的值重疊。要想建立在整個(gè)表的生命周期中唯一的鍵值,需要在 INTEGER PRIMARY KEY 上增加AUTOINCREMENT聲明。那么,新的鍵值將會比該表中曾能存在過的***值大1。如果***可能的整數(shù)值在數(shù)據(jù)表中曾經(jīng)存在過,INSERT將會失敗, 并返回SQLITE_FULL錯(cuò)誤代碼。
(2)SQLite支持何種數(shù)據(jù)類型?參見 http://www.sqlite.org/datatype3.html.
(3)SQLite允許向一個(gè)integer型字段中插入字符串!
這是一個(gè)特性,而不是一個(gè)bug。SQLite不強(qiáng)制數(shù)據(jù)類型約束。任何數(shù)據(jù)都可以插入任何列。你可以向一個(gè)整型列中插入任意長度的字符串, 向布爾型列中插入浮點(diǎn)數(shù),或者向字符型列中插入日期型值。 在 CREATE TABLE 中所指定的數(shù)據(jù)類型不會限制在該列中插入任何數(shù)據(jù)。 任何列均可接受任意長度的字符串(只有一種情況除外:標(biāo)志為INTEGER PRIMARY KEY的列只能存儲64位整數(shù), 當(dāng)向這種列中插數(shù)據(jù)除整數(shù)以外的數(shù)據(jù)時(shí),將會產(chǎn)生錯(cuò)誤。
但SQLite確實(shí)使用聲明的列類型來指示你所期望的格式。所以,例如你向一個(gè)整型列中插入字符串時(shí),SQLite會試圖將該字符串轉(zhuǎn)換成一個(gè)整數(shù)。 如果可以轉(zhuǎn)換,它將插入該整數(shù);否則,將插入字符串。這種特性有時(shí)被稱為 類型或列親和性(type or column affinity).
(4)為什么SQLite不允許在同一個(gè)表不同的兩行上使用0和0.0作主鍵?
主鍵必須是數(shù)值類型,將主鍵改為TEXT型將不起作用。
每一行必須有一個(gè)唯一的主鍵。對于一個(gè)數(shù)值型列, SQLite認(rèn)為 '0' 和 '0.0' 是相同的,因?yàn)樗麄冊谧鳛檎麛?shù)比較時(shí)是相等的(參見上一問題)。 所以,這樣值就不唯一了。
(5)多個(gè)應(yīng)用程序或一個(gè)應(yīng)用程序的多個(gè)實(shí)例可以同時(shí)訪問同一個(gè)數(shù)據(jù)庫文件嗎?
多個(gè)進(jìn)程可同時(shí)打開同一個(gè)數(shù)據(jù)庫。多個(gè)進(jìn)程可以同時(shí)進(jìn)行SELECT 操作,但在任一時(shí)刻,只能有一個(gè)進(jìn)程對數(shù)據(jù)庫進(jìn)行更改。
SQLite使用讀、寫鎖控制對數(shù)據(jù)庫的訪問。(在Win95/98/ME等不支持讀、寫鎖的系統(tǒng)下,使用一個(gè)概率性的模擬來代替。)但使用時(shí)要注意: 如果數(shù)據(jù)庫文件存放于一個(gè)NFS文件系統(tǒng)上,這種鎖機(jī)制可能不能正常工作。這是因?yàn)?fcntl() 文件鎖在很多NFS上沒有正確的實(shí)現(xiàn)。
在可能有多個(gè)進(jìn)程同時(shí)訪問數(shù)據(jù)庫的時(shí)候,應(yīng)該避免將數(shù)據(jù)庫文件放到NFS上。 在Windows上,Microsoft的文檔中說:如果使用 FAT 文件系統(tǒng)而沒有運(yùn)行 share.exe 守護(hù)進(jìn)程,那么鎖可能是不能正常使用的。那些在Windows上有很多經(jīng)驗(yàn)的人告訴我:對于網(wǎng)絡(luò)文件,文件鎖的實(shí)現(xiàn)有好多Bug,是靠不住的。如果他們說的是對的,那么在兩臺或多臺Windows機(jī)器間共享數(shù)據(jù)庫可能會引起不期望的問題。
我們意識到,沒有其它嵌入式的 SQL 數(shù)據(jù)庫引擎能象 SQLite 這樣處理如此多的并發(fā)。SQLite允許多個(gè)進(jìn)程同時(shí)打開一個(gè)數(shù)據(jù)庫,同時(shí)讀一個(gè)數(shù)據(jù)庫。當(dāng)有任何進(jìn)程想要寫時(shí),它必須在更新過程中鎖住數(shù)據(jù)庫文件。但那通常只是幾毫秒的時(shí)間。其它進(jìn)程只需等待寫進(jìn)程干完活結(jié)束。典型地,其它嵌入式的SQL數(shù)據(jù)庫引擎同時(shí)只允許一個(gè)進(jìn)程連接到數(shù)據(jù)庫。
但是,Client/Server數(shù)據(jù)庫引擎(如 PostgreSQL, MySQL, 或 Oracle)通常支持更高級別的并發(fā),并且允許多個(gè)進(jìn)程同時(shí)寫同一個(gè)數(shù)據(jù)庫。 這種機(jī)制在Client/Server結(jié)構(gòu)的數(shù)據(jù)庫上是可能的,因?yàn)榭偸怯幸粋€(gè)單一的服務(wù)器進(jìn)程很好地控制、協(xié)調(diào)對數(shù)據(jù)庫的訪問。如果你的應(yīng)用程序需要很多的并發(fā),那么你應(yīng)該考慮使用一個(gè)Client/Server 結(jié)構(gòu)的數(shù)據(jù)庫。但經(jīng)驗(yàn)表明,很多應(yīng)用程序需要的并發(fā),往往比其設(shè)計(jì)者所想象的少得多。
當(dāng)SQLite試圖訪問一個(gè)被其它進(jìn)程鎖住的文件時(shí),缺省的行為是返回 SQLITE_BUSY??梢栽贑代碼中使用 sqlite 3_busy_handler() 或 sqlite 3_busy_timeout() API 函數(shù)調(diào)整這一行為。
小結(jié):關(guān)于SQLite常見問題解答的內(nèi)容介紹完了,希望通過本文的學(xué)習(xí)能對你有所幫助!