官網 SQLite是一款輕型的數據庫,是關系型數據庫(RDBMS)管理系統,它包含在一個相對小的C庫中。目前在很多嵌入式產品中使用了它,它占用資源非常 的低,在嵌入式設備中,可能只需要幾百K的內存就夠了。它能夠支持Windows/Linux/Unix/Android/IOS等等主流的操作系統,同 時能夠跟很多程序語言相結合,比如 Tcl、C#、PHP、Java等,還有ODBC接口,同樣比起Mysql、PostgreSQL這兩款開源的世界著名數據庫管理系統來講,它的處理速度 比他們都快。
Sqlite命令分類:
(DDL)數據定義語言:
CMD | Description |
---|---|
CREATE | 創建一個新的表,一個表的視圖,或者數據庫中的其他對象。 |
ALTER | 修改數據庫中的某個已有的數據庫對象,比如一個表。 |
DROP | 刪除整個表,或者表的視圖,或者數據庫中的其他對象。 |
(DML)數據操作語言:
CMD | Description |
---|---|
INSERT | 創建一條記錄。 |
UPDATE | 修改記錄。 |
DELETE | 刪除記錄。 |
(DQL)數據查詢語言:
CMD | Description |
---|---|
SELECT | 從一個或多個表中檢索某些記錄。 |
Sqlite點命令
先看一張Windows下的截圖:
這是在Windows的cmd下運行sqlite3命令(如何安裝和配置煩請自行google | baidu),然后依據提示運行.help的打印(只截圖一部分)。
可以發現sqlite的help列出來了所有sqlite支持的點命令,也可以發現,點命令不需要已”;”結尾。
我們對上面的.help命令進行翻譯大致如下:
CMD | Description |
---|---|
.backup ?DB? FILE |
備份DB數據庫(默認是”main”)到FILE文件。 |
.bail ON/OFF |
發生錯誤后停止。默認為OFF。 |
.databases |
列出附加數據庫的名稱和文件。 |
.dump ?TABLE? |
以SQL文本格式轉儲數據庫。如果指定了TABLE表,則只轉儲匹配LIKE模式的TABLE表。 |
.echo ON/OFF |
開啟或關閉echo命令。 |
.exit |
退出SQLite提示符。 |
.explain ON/OFF |
開啟或關閉適合於EXPLAIN的輸出模式。如果沒有帶參數,則為EXPLAIN on,及開啟EXPLAIN。 |
.header(s) ON/OFF |
開啟或關閉頭部顯示。 |
.help |
顯示消息。 |
.import FILE TABLE |
導入來自FILE文件的數據到TABLE表中。 |
.indices ?TABLE? |
顯示所有索引的名稱。如果指定了TABLE表,則只顯示匹配LIKE模式的TABLE表的索引。 |
.load FILE ?ENTRY? |
加載一個擴展庫。 |
.log FILE/off |
開啟或關閉日志。FILE文件可以是stderr(標准錯誤)/stdout(標准輸出)。 |
.mode MODE |
設置輸出模式,MODE可以是下列之一:csv 逗號分隔的值;column 左對齊的列;html HTML的<table> 代碼;insert TABLE表的SQL插入(insert)語句;line 每行一個值;list 由 .separator字符串分隔的值;tabs 由Tab分隔的值;tcl TCL列表元素。 |
.nullvalue STRING |
在NULL值的地方輸出STRING字符串。 |
.output FILENAME |
發送輸出到FILENAME文件。 |
.output stdout |
發送輸出到屏幕。 |
.print STRING... |
逐字地輸出STRING字符串。 |
.prompt MAIN CONTINUE |
替換標准提示符。 |
.quit |
退出SQLite提示符。 |
.read FILENAME |
執行FILENAME文件中的SQL。 |
.schema ?TABLE? |
顯示CREATE語句。如果指定了TABLE表,則只顯示匹配LIKE模式的TABLE表。 |
.separator STRING |
改變輸出模式和.import所使用的分隔符。 |
.show |
顯示各種設置的當前值。 |
.stats ON/OFF |
開啟或關閉統計。 |
.tables ?PATTERN? |
列出匹配LIKE模式的表的名稱。 |
.timeout MS |
嘗試打開鎖定的表MS微秒。 |
.width NUM NUM |
為”column”模式設置列寬度。 |
.timer ON/OFF |
開啟或關閉CPU定時器測量。 |
Sqlite數據庫的sqlite_master表
主表中保存數據庫表的關鍵信息,並把它命名為sqlite_master。如要查看表概要,可如下操作:
sqlite>.schema sqlite_master
Sqlite語法規則
SQLite是遵循一套獨特的稱為語法的規則和准則。
SQLite是不區分大小寫的,但也有一些命令是大小寫敏感的,比如GLOB和glob在SQLite的語句中有不同的含義。
SQLite 注釋是附加的注釋,可以在 SQLite 代碼中添加注釋以增加其可讀性,他們可以出現在任何空白處,包括在表達式內和其他 SQL 語句的中間,但它們不能嵌套。
SQL注釋以兩個連續的”-“字符開始,並擴展至下一個換行符或直到輸入結束,以先到者為准。也可以以”/*"
開始,並擴展至下一個 “*/
” 字符對或直到輸入結束,以先到者為准。SQLite的注釋可以跨越多行。
SQLite語句以任何關鍵字開始,以”;”結束。
Sqlite數據類型
SQLite數據類型是一個用來指定任何對象的數據類型的屬性。SQLite 中的每一列,每個變量和表達式都有相關的數據類型。您可以在創建表的同時使用這些數據類型。SQLite使用一個更普遍的動態類型系統。在SQLite 中,值的數據類型與值本身是相關的,而不是與它的容器相關。
存儲類
SQLite有5個原始的數據類型,被稱為存儲類。存儲類這個詞表明了一個值在磁盤上存儲的格式,其實就是類型或數據類型的同義詞。如下即是存儲類:
存儲類 | Description |
---|---|
NULL | 值是一個NULL值。 |
INTEGER | 值是一個帶符號的整數,根據值的大小存儲在1、2、3、4、6 或8字節中。 |
REAL | 值是一個浮點值,存儲為8字節的IEEE浮點數字。 |
TEXT | 值是一個文本字符串,使用數據庫編碼(UTF-8、UTF-16BE或UTF-16LE)存儲。 |
BLOB | 值是一個blob數據,完全根據它的輸入存儲。 |
SQLite通過值的表示法來判斷其類型,下面就是SQLite的推理方法:
- SQL語句中用單引號或雙引號括起來的文字被指派為TEXT。
- 如果文字是未用引號括起來的數據,並且沒有小數點和指數,被指派為INTEGER。
- 如果文字是未用引號括起來的數據,並且帶有小數點或指數,被指派為REAL。
- 用NULL說明的值被指派為NULL存儲類。
- 如果一個值的格式為X’ABCD’,其中ABCD為16進制數字,則該值被指派為BLOB。X前綴大小寫皆可。
如下就是驗證結果:
SQLite單獨的一個字段可能包含不同存儲類的值。
如下就是驗證結果:
喜歡鑽牛角尖的這時候指定開始BB了,temp這一列數據類型不同,咋樣比較大小?咋樣排序等等?
經過查閱資料發現,具有不同存儲類的值可以存儲在同一個字段中。可以被排序,因為這些值可以相互比較。有完善定義的規則來做這件事。不同存儲類的值可以通過它們各自類的“類值”進行排序,定義如下:
- NULL存儲類具有最低的類值。一個具有NULL存儲類的值比所有其它值都小(包括其它具有NULL存儲類的值)。在NULL值之間,沒有特別的可排序值。
- INTEGER或REAL存儲類值高於NULL,它們的類值相等。INTEGER值和REAL值通過其數值進行比較。
- TEXT存儲類的值比INTEGER和REAL高。數值永遠比字符串的值低。當兩個TEXT值進行比較時,其值大小由“排序法”決定。
- BLOB存儲類具有最高的類值。具有BLOB類的值大於其它所有類的值。BLOB值之間在比較時使用C函數memcmp()。
所以,當SQLite對一個字段進行排序時,首先按存儲類排序,然后再進行類內的排序 (NULL類內部各值不必排序) 。
弱類型(manifest typing)
首先有如下SQL語句:
CREATE TABLE table_yanbo( x integer, y text, z real ); INSERT INTO table_yanbo VALUES ('1', '1', '1');
這里的x、y和z這3個字段中存儲的是INTEGER, TEXT和REAL類型。
再看下面例子:
CREATE TABLE table_yanbo(x, y, z); INSERT INTO table_yanbo VALUES ('1', '1', '1');
這里的x、y和z這3個字段中存儲的是TEXT、TEXT和TEXT類型。
再看下面例子:
CREATE TABLE table_yanbo(x, y, z); INSERT INTO table_yanbo VALUES (1, 1.0, x'10');
這里的x、y和z這3個字段中存儲的是INTEGER、REAL和BLOB類型。
通過上面幾種寫法你會發現,可以為SQLite的字段定義類型,但這不是必須的,你可以盡管違反類型定義。這是因為在任何情況下,SQLite都可以接受一個值並推斷它的類型。
總之,SQLite的弱類型可表示為:
- 字段可以有類型。
- 類型可以通過值來推斷。
類型親和性介紹這兩個規定如何相互關聯。所謂類型親和性就是在強類型(strict typing)和動態類型(dynamic typing)之間的平衡藝術。
類型親和性(Type Affinity)
在SQLite中,字段沒有類型或域。當給一個字段聲明了類型,該字段實際上僅僅具有了該類型的親和性。聲明類型和類型親和性是兩回事。類型親和性 預定SQLite用什么存儲類在字段中存儲值。在存儲一個給定的值時到底SQLite會在該字段中用什么存儲類決定於值的存儲類和字段親和性的結合。
任何列可以存儲任何類型的數據,但列的首選存儲類是它的affinity。在SQLite3數據庫中,每個表的列分配為以下類型的affinity之一:
Affinity | Description |
---|---|
TEXT | 該列使用存儲類NULL、TEXT或BLOB存儲所有數據。 |
NUMERIC | 該列可以包含使用所有五個存儲類的值。 |
INTEGER | 與帶有NUMERIC affinity的列相同,在CAST表達式中帶有異常。 |
REAL | 與帶有NUMERIC affinity的列相似,不同的是,它會強制把整數值轉換為浮點表示。 |
NONE | 帶有affinity NONE的列,不會優先使用哪個存儲類,也不會嘗試把數據從一個存儲類強制轉換為另一個存儲類。 |
下表列出了當創建SQLite3表時可使用的各種數據類型名稱,同時也顯示了相應的應用Affinity:
數據類型 | Affinity |
---|---|
INT、NTEGER、TINYINT、SMALLINT、MEDIUMINT、BIGINT、UNSIGNED BIG INT、INT2、INT8 | INTEGER |
CHARACTER(20)、VARCHAR(255)、VARYING CHARACTER(255)、NCHAR(55)、NATIVE CHARACTER(70)、NVARCHAR(100)、TEXT、CLOB | TEXT |
BLOB、no datatype specified | NONE |
REAL、DOUBLE、DOUBLE PRECISION、FLOAT | REAL |
NUMERIC、DECIMAL(10,5)、BOOLEAN、DATE、DATETIME | NUMERIC |
Boolean數據類型
SQLite沒有單獨的Boolean存儲類,布爾值被存儲為整數 0(false)和 1(true)。
Date與Time數據類型
SQLite沒有一個單獨的用於存儲日期和/或時間的存儲類,但SQLite 能夠把日期和時間存儲為TEXT、REAL或 INTEGER值。您可以以任何上述格式來存儲日期和時間,並且可以使用內置的日期和時間函數來自由轉換不同格式。
存儲類 | 日期格式 |
---|---|
TEXT | 格式為”YYYY-MM-DD HH:MM:SS.SSS”的日期。 |
REAL | 從公元前4714年11月24日格林尼治時間的正午開始算起的天數。 |
INTEGER | 從1970-01-01 00:00:00 UTC算起的秒數。 |
字段類型和親和性
首先,每個字段都具有一種親和性。共有五種親和性:NUMERIC、INTEGER、REAL、TEXT和NONE。一個字段的親和性由它預聲明的類型決定。所以,當你為字段聲明了類型,從根本上說是為字段指定了親和性。SQLite按下面的規則為字段指派親和性:
- 默認的,一個字段默認的親和性是NUMERIC。如果一個字段不是INTEGER、TEXT、REAL或NONE的,那它自動地被指派為NUMERIC親和性。
- 如果為字段聲明的類型中包含了’INT’(無論大小寫),該字段被指派為INTEGER親和性。
- 如果為字段聲明的類型中包含了’CHAR’、’CLOB’或’TEXT’(無論大小寫),該字段被指派為TEXT親和性。如’VARCHAR’包含了’CHAR’,所以被指派為TEXT親和性。
- 如果為字段聲明的類型中包含了’BLOB’(無論大小寫),或者沒有為該字段聲明類型,該字段被指派為NONE親和性。
注意:如果沒有為字段聲明類型,該字段的親和性為NONE,在這種情況下,所有的值都將以它們本身的(或從它們的表示法中推斷的)存儲類存儲。如果 你暫時還不確定要往一個字段里放什么內容,或准備將來修改,用NONE親和性是一個好的選擇。但SQLite默認的親和性是NUMERIC。例如,如果為 一定字段聲明了類型JUJYFRUIT,該字段的親和性不是NONE,因為SQLite不認識這種類型,會給它指派默認的NUMERIC親和性。所以,與 其用一個不認識的類型最終得到NUMERIC親和性,還不如不為它指定類型,從而使它得到NONE親和性。
親和性和存儲
親和性對值如何存儲到字段有影響,規則如下:
- 一個NUMERIC字段可能包括所有5種存儲類。一個NUMERIC字段具有數字存儲類的偏好(INTEGER和REAL)。當一個TEXT值被 插入到一個NUMERIC字段,將會試圖將其轉化為INTEGER存儲類;如果轉化失敗,將會試圖將其轉化為REAL存儲類;如果還是失敗,將會用 TEXT存儲類來存儲。
- 一個INTEGER字段的處理很像NUMERIC字段。一個INTEGER字段會將REAL值按REAL存儲類存儲。也就是說,如果這個REAL 值沒有小數部分,就會被轉化為INTEGER存儲類。INTEGER字段將會試着將TEXT值按REAL存儲;如果轉化失敗,將會試圖將其轉化為 INTEGER存儲類;如果還是失敗,將會用TEXT存儲類來存儲。
- 一個TEXT字段將會把所有的INTEGER或REAL值轉化為TEXT。
- 一個NONE字段不試圖做任何類型轉化。所有值按它們本身的存儲類存儲。
- 沒有字段試圖向NULL或BLOB值轉化——如無論用什么親和性。NULL和BLOB值永遠都按本來的方式存儲在所有字段。
這些規則初看起來比較復雜,但總的設計目標很簡單,如果你需要,SQLite會盡量模仿其它的關系型數據庫。也就是說,如果你將SQLite看成是 一個傳統數據庫,類型親和性將會按你的期望來存儲值。如果你聲明了一個INTEGER字段,並向里面放一個整數,就會按整數來存儲。如果你聲明了一個具有 TEXT, CHAR或VARCHAR類型的字段並向里放一個整數,整數將會轉化為TEXT。可是,如果你不遵守這些規定,SQLite也會找到辦法來存儲你的值。
如下例子展示了親和性是如何工作的:
存儲類和類型轉換
關於存儲類,需要關注的另一件事是存儲類有時會影響到值如何進行比較。特別是SQLite有時在進行比較之前,會將值在數字存儲類(INTEGER和REAL)和TEXT之間進行轉換。為進行二進制的比較,遵循如下規則:
- 當一個字段值與一個表達式的結果進行比較,字段的親和性會在比較之前應用於表達式的結果。
- 當兩個字段值進行比較,如果一個字段擁有INTEGER或NUMERIC親和性而另一個沒有,NUMERIC親和性會應用於非NUMERIC字段的TEXT值。
- 當兩個表達式進行比較,SQLite不做任何轉換。如果兩個表達式有相似的存儲類,則直接按它們的值進行比較;否則按類值進行比較。
總結
這里主要介紹了Sqlite的一些基本概念和數據類型的特性。關於Sqlite其他內容接下來文章繼續介紹。