Android數(shù)據(jù)庫(kù)瘫絮,第二篇涨冀。(主要就是研究Sqlite數(shù)據(jù)庫(kù)的高級(jí)屬性)

前言

我們是接著上一篇寫的Android數(shù)據(jù)庫(kù),第二篇麦萤。(主要就是研究Sqlite數(shù)據(jù)庫(kù))

繼續(xù)開(kāi)車::

12).SQLite 視圖(View)(是只讀的無(wú)法在試圖上鹿鳖,執(zhí)行DELETE、INSERT和UPDATE語(yǔ)句)
視圖(View)只不過(guò)是通過(guò)相關(guān)的名稱存儲(chǔ)在數(shù)據(jù)庫(kù)中的一個(gè) SQLite 語(yǔ)句壮莹。視圖(View)實(shí)際上是一個(gè)以預(yù)定義的 SQLite 查詢形式存在的表的組合翅帜。
視圖(View)可以包含一個(gè)表的所有行或從一個(gè)或多個(gè)表選定行。視圖(View)可以從一個(gè)或多個(gè)表創(chuàng)建垛孔,這取決于要?jiǎng)?chuàng)建視圖的 SQLite 查詢藕甩。
視圖(View)是一種虛表,允許用戶實(shí)現(xiàn)以下幾點(diǎn):
1.用戶或用戶組查找結(jié)構(gòu)數(shù)據(jù)的方式更自然或直觀周荐。
2.限制數(shù)據(jù)訪問(wèn)狭莱,用戶只能看到有限的數(shù)據(jù),而不是完整的表概作。
3.匯總各種表中的數(shù)據(jù)腋妙,用于生成報(bào)告。

SQLite 視圖是只讀的讯榕,因此可能無(wú)法在視圖上執(zhí)行 DELETE骤素、INSERT 或 UPDATE 語(yǔ)句匙睹。但是可以在視圖上創(chuàng)建一個(gè)觸發(fā)器,當(dāng)嘗試 DELETE济竹、INSERT 或 UPDATE 視圖時(shí)觸發(fā)痕檬,需要做的動(dòng)作在觸發(fā)器內(nèi)容中定義。
基本指令:

創(chuàng)建視圖
SQLite 的視圖是使用 CREATE VIEW 語(yǔ)句創(chuàng)建的送浊。SQLite 視圖可以從一個(gè)單一的表梦谜、多個(gè)表或其他視圖創(chuàng)建。
CREATE VIEW 的基本語(yǔ)法如下:

CREATE [TEMP | TEMPORARY] VIEW view_name AS
SELECT column1, column2.....
FROM table_name
WHERE [condition];
您可以在 SELECT 語(yǔ)句中包含多個(gè)表袭景,這與在正常的 SQL SELECT 查詢中的方式非常相似唁桩。如果使用了可選的 TEMP 或 TEMPORARY 關(guān)鍵字,則將在臨時(shí)數(shù)據(jù)庫(kù)中創(chuàng)建視圖耸棒。

創(chuàng)建視圖::
假設(shè) COMPANY 表有以下記錄:

ID | NAME | AGE | ADDRESS | SALARY
-----|----- ---------- ---------- ---------- ----------
1 | Paul | 32 | California | 20000.0
2 | Allen | 25 | Texas | 15000.0
3 | Teddy | 23 | Norway | 20000.0
4 | Mark | 25 | Rich-Mond | 65000.0
5 | David | 27 | Texas | 85000.0
6 | Kim | 22 | South-Hall| 45000.0
7 | James | 24 | Houston | 10000.0
現(xiàn)在荒澡,下面是一個(gè)從 COMPANY 表創(chuàng)建視圖的實(shí)例。視圖只從 COMPANY 表中選取幾列:

sqlite> CREATE VIEW COMPANY_VIEW AS
SELECT ID, NAME, AGE
FROM  COMPANY;
現(xiàn)在与殃,可以查詢 COMPANY_VIEW单山,與查詢實(shí)際表的方式類似。下面是實(shí)例:
sqlite> SELECT * FROM COMPANY_VIEW;

這將產(chǎn)生以下結(jié)果:

ID | NAME | AGE
----|------ ---------- ----------
1 | Paul | 32
2 | Allen | 25
3 | Teddy | 23
4 | Mark | 25
5 | David | 27
6 | Kim | 22
7 | James | 24
分析:上面給人的感覺(jué)就好像是表的一個(gè)影子奈籽,只能查詢饥侵,不能做其他的操作。

刪除視圖:
要?jiǎng)h除視圖衣屏,只需使用帶有 view_name 的 DROP VIEW 語(yǔ)句。DROP VIEW 的基本語(yǔ)法如下:
sqlite> DROP VIEW view_name;
下面的命令將刪除我們?cè)谇懊鎰?chuàng)建的 COMPANY_VIEW 視圖:
sqlite> DROP VIEW COMPANY_VIEW;

13).SQLite 事務(wù)(Transaction)
事務(wù)(Transaction)是一個(gè)對(duì)數(shù)據(jù)庫(kù)執(zhí)行工作單元辩棒。事務(wù)(Transaction)是以邏輯順序完成的工作單位或序列狼忱,可以是由用戶手動(dòng)操作完成,也可以是由某種數(shù)據(jù)庫(kù)程序自動(dòng)完成一睁。
事務(wù)(Transaction)是指一個(gè)或多個(gè)更改數(shù)據(jù)庫(kù)的擴(kuò)展钻弄。例如,如果您正在創(chuàng)建一個(gè)記錄或者更新一個(gè)記錄或者從表中刪除一個(gè)記錄者吁,那么您正在該表上執(zhí)行事務(wù)窘俺。重要的是要控制事務(wù)以確保數(shù)據(jù)的完整性和處理數(shù)據(jù)庫(kù)錯(cuò)誤。
實(shí)際上复凳,您可以把許多的 SQLite 查詢聯(lián)合成一組瘤泪,把所有這些放在一起作為事務(wù)的一部分進(jìn)行執(zhí)行。
>>事務(wù)的屬性
事務(wù)(Transaction)具有以下四個(gè)標(biāo)準(zhǔn)屬性育八,通常根據(jù)首字母縮寫為 ACID:
>原子性(Atomicity):確保工作單位內(nèi)的所有操作都成功完成对途,否則,事務(wù)會(huì)在出現(xiàn)故障時(shí)終止髓棋,之前的操作也會(huì)回滾到以前的狀態(tài)实檀。
>一致性(Consistency):確保數(shù)據(jù)庫(kù)在成功提交的事務(wù)上正確地改變狀態(tài)惶洲。
>隔離性(Isolation):使事務(wù)操作相互獨(dú)立和透明。
>持久性(Durability):確保已提交事務(wù)的結(jié)果或效果在系統(tǒng)發(fā)生故障的情況下仍然存在膳犹。

事務(wù)控制
使用下面的命令來(lái)控制事務(wù):
BEGIN TRANSACTION:開(kāi)始事務(wù)處理恬吕。
COMMIT:保存更改,或者可以使用 END TRANSACTION 命令须床。
ROLLBACK:回滾所做的更改币呵。
事務(wù)控制命令只與 DML 命令 INSERT、UPDATE 和 DELETE 一起使用侨颈。他們不能在創(chuàng)建表或刪除表時(shí)使用余赢,因?yàn)檫@些操作在數(shù)據(jù)庫(kù)中是自動(dòng)提交的。

BEGIN TRANSACTION 命令
事務(wù)(Transaction)可以使用 BEGIN TRANSACTION 命令或簡(jiǎn)單的 BEGIN 命令來(lái)啟動(dòng)哈垢。此類事務(wù)通常會(huì)持續(xù)執(zhí)行下去妻柒,直到遇到下一個(gè) COMMIT 或 ROLLBACK 命令。不過(guò)在數(shù)據(jù)庫(kù)關(guān)閉或發(fā)生錯(cuò)誤時(shí)耘分,事務(wù)處理也會(huì)回滾举塔。以下是啟動(dòng)一個(gè)事務(wù)的簡(jiǎn)單語(yǔ)法:
BEGIN;或者是( BEGIN TRANSACTION;)這樣就開(kāi)啟事務(wù)了。

>COMMIT 命令
COMMIT 命令是用于把事務(wù)調(diào)用的更改保存到數(shù)據(jù)庫(kù)中的事務(wù)命令求泰。
COMMIT 命令把自上次 COMMIT 或 ROLLBACK 命令以來(lái)的所有事務(wù)保存到數(shù)據(jù)庫(kù)央渣。
COMMIT 命令的語(yǔ)法如下:
COMMIT;(END TRANSACTION;)結(jié)束或者是提交命令。

>ROLLBACK 命令
ROLLBACK 命令是用于撤消尚未保存到數(shù)據(jù)庫(kù)的事務(wù)的事務(wù)命令渴频。
ROLLBACK 命令只能用于撤銷自上次發(fā)出 COMMIT 或 ROLLBACK 命令以來(lái)的事務(wù)芽丹。
ROLLBACK 命令的語(yǔ)法如下:
ROLLBACK;  只有這么一種表現(xiàn)形式。

實(shí)戰(zhàn):
假設(shè) COMPANY 表有以下記錄:

ID | NAME | AGE | ADDRESS | SALARY
-----|----- ---------- ---------- ---------- ----------
1 | Paul | 32 | California | 20000.0
2 | Allen | 25 | Texas | 15000.0
3 | Teddy | 23 | Norway | 20000.0
4 | Mark | 25 | Rich-Mond | 65000.0
5 | David | 27 | Texas | 85000.0
6 | Kim | 22 | South-Hall | 45000.0
7 | James | 24 | Houston | 10000.0
現(xiàn)在卜朗,讓我們開(kāi)始一個(gè)事務(wù)拔第,并從表中刪除 age = 25 的記錄,最后场钉,我們使用 ROLLBACK 命令撤消所有的更改蚊俺。

sqlite> BEGIN;
sqlite> DELETE FROM COMPANY WHERE AGE = 25;
sqlite> ROLLBACK;

檢查 COMPANY 表,仍然有以下記錄:

ID | NAME | AGE | ADDRESS| SALARY
-----|----- ---------- ---------- ---------- ----------
1 | Paul | 32 | California| 20000.0
2 | Allen | 25 | Texas | 15000.0
3 | Teddy | 23 | Norway | 20000.0
4 | Mark | 25 | Rich-Mond | 65000.0
5 | David | 27 | Texas | 85000.0
6 | Kim | 22 | South-Hall | 45000.0
7 | James | 24 | Houston | 10000.0
現(xiàn)在逛万,讓我們開(kāi)始另一個(gè)事務(wù)泳猬,從表中刪除 age = 25 的記錄,最后我們使用 COMMIT 命令提交所有的更改宇植。

sqlite> BEGIN;
sqlite> DELETE FROM COMPANY WHERE AGE = 25;
sqlite> COMMIT;

檢查 COMPANY 表得封,有以下記錄:

ID | NAME | AGE | ADDRESS | SALARY
-----|----- ---------- ---------- ---------- ----------
1 | Paul | 32 | California| 20000.0
3 | Teddy | 23 | Norway | 20000.0
5 | David | 27 | Texas | 85000.0
6 | Kim | 22 | South-Hall| 45000.0
7 | James | 24 | Houston | 10000.0
注意:最后的生效還是commit好用。
14).SQLite 子查詢
子查詢或內(nèi)部查詢或嵌套查詢是在另一個(gè) SQLite 查詢內(nèi)嵌入在 WHERE 子句中的查詢当纱。
使用子查詢返回的數(shù)據(jù)將被用在主查詢中作為條件呛每,以進(jìn)一步限制要檢索的數(shù)據(jù)。
子查詢可以與 SELECT坡氯、INSERT晨横、UPDATE 和 DELETE 語(yǔ)句一起使用洋腮,可伴隨著使用運(yùn)算符如 =、<手形、>啥供、>=、<=库糠、IN伙狐、BETWEEN 等。
必須遵循的幾個(gè)規(guī)則:
>子查詢必須用括號(hào)括起來(lái)瞬欧。
>子查詢?cè)?SELECT 子句中只能有一個(gè)列贷屎,除非在主查詢中有多列,與子查詢的所選列進(jìn)行比較艘虎。
>ORDER BY 不能用在子查詢中唉侄,雖然主查詢可以使用 ORDER BY∫敖ǎ可以在子查詢中使用 GROUP BY属划,功能與 ORDER BY 相同。
>子查詢返回多于一行候生,只能與多值運(yùn)算符一起使用同眯,如 IN 運(yùn)算符。
>BETWEEN 運(yùn)算符不能與子查詢一起使用唯鸭,但是须蜗,BETWEEN 可在子查詢內(nèi)使用。

SELECT語(yǔ)句中的子查詢使用:
子查詢通常與 SELECT 語(yǔ)句一起使用肿孵∵胫啵基本語(yǔ)法如下:
SELECT column_name [, column_name ]
FROM   table1 [, table2 ]
WHERE  column_name OPERATOR
  (SELECT column_name [, column_name ]
  FROM table1 [, table2 ]
  [WHERE])

實(shí)戰(zhàn):sqlite> SELECT * 
        FROM COMPANY 
        WHERE ID IN (SELECT ID 
                    FROM COMPANY 
                    WHERE SALARY > 45000) ;
 最后的結(jié)果就是打印出所有大于45000的數(shù)據(jù)。

INSERT 語(yǔ)句中的子查詢使用:(這就是復(fù)制表格巴W觥!大莫!

子查詢也可以與 INSERT 語(yǔ)句一起使用蛉腌。INSERT 語(yǔ)句使用子查詢返回的數(shù)據(jù)插入到另一個(gè)表中。在子查詢中所選擇的數(shù)據(jù)可以用任何字符只厘、日期或數(shù)字函數(shù)修改烙丛。
基本語(yǔ)法如下:
INSERT INTO table_name [ (column1 [, column2 ]) ]
           SELECT [ *|column1 [, column2 ]
           FROM table1 [, table2 ]
           [ WHERE VALUE OPERATOR ]
實(shí)戰(zhàn):
假設(shè) COMPANY_BKP 的結(jié)構(gòu)與 COMPANY 表相似,且可使用相同的 CREATE TABLE 進(jìn)行創(chuàng)建羔味,只是表名改為 COMPANY_BKP『友剩現(xiàn)在把整個(gè) COMPANY 表復(fù)制到 COMPANY_BKP,語(yǔ)法如下:
sqlite> INSERT INTO COMPANY_BKP
     SELECT * FROM COMPANY 
     WHERE ID IN (SELECT ID 
                  FROM COMPANY) ;

UPDATE 語(yǔ)句中的子查詢使用

子查詢可以與 UPDATE 語(yǔ)句結(jié)合使用赋元。當(dāng)通過(guò) UPDATE 語(yǔ)句使用子查詢時(shí)忘蟹,表中單個(gè)或多個(gè)列被更新飒房。
基本語(yǔ)法如下:
UPDATE table
SET column_name = new_value
[ WHERE OPERATOR [ VALUE ]
   (SELECT COLUMN_NAME
   FROM TABLE_NAME)
   [ WHERE) ]
需要上面的表輔助,意思就是兩個(gè)表格是一樣的媚值。哪個(gè)數(shù)值進(jìn)行操作放到這個(gè)表里面狠毯。
實(shí)戰(zhàn):
我們有 COMPANY_BKP 表,是 COMPANY 表的備份褥芒。
下面的實(shí)例把 COMPANY 表中所有 AGE 大于或等于 27 的客戶的 SALARY 更新為原來(lái)的 0.50 倍:
sqlite> UPDATE COMPANY
     SET SALARY = SALARY * 0.50
     WHERE AGE IN (SELECT AGE FROM COMPANY_BKP
                   WHERE AGE >= 27 );

DELETE語(yǔ)句中的子查詢使用:

基本語(yǔ)法如下:
DELETE FROM TABLE_NAME
[ WHERE OPERATOR [ VALUE ]
   (SELECT COLUMN_NAME
   FROM TABLE_NAME)
   [ WHERE) ]
實(shí)戰(zhàn):
假設(shè)嚼松,我們有 COMPANY_BKP 表,是 COMPANY 表的備份锰扶。
下面的實(shí)例刪除 COMPANY 表中所有 AGE 大于或等于 27 的客戶記錄:
sqlite> DELETE FROM COMPANY
    WHERE AGE IN (SELECT AGE FROM COMPANY_BKP
               WHERE AGE > 27 );

這將影響兩行献酗,最后 COMPANY 表中的記錄如下:

ID | NAME | AGE | ADDRESS | SALARY
-----|----- ---------- ---------- ---------- ----------
2 | Allen | 25 | Texas | 15000.0
3 | Teddy | 23 | Norway | 20000.0
4 | Mark | 25 | Rich-Mond | 65000.0
5 | David | 27 | Texas | 42500.0
6 | Kim | 22 | South-Hall |45000.0
7 | James | 24 | Houston | 10000.0
15).SQLite Autoincrement(自動(dòng)遞增)
SQLite 的 AUTOINCREMENT 是一個(gè)關(guān)鍵字,用于表中的字段值自動(dòng)遞增坷牛。我們可以在創(chuàng)建表時(shí)在特定的列名稱上使用 AUTOINCREMENT 關(guān)鍵字實(shí)現(xiàn)該字段值的自動(dòng)增加罕偎。

關(guān)鍵字 AUTOINCREMENT 只能用于整型(INTEGER)字段。
基本語(yǔ)法:
就是在在建表的時(shí)候使用:
CREATE TABLE table_name(
   column1 INTEGER AUTOINCREMENT,
   column2 datatype,
   column3 datatype,
   .....
   columnN datatype,
);
實(shí)戰(zhàn)就是:向表格里面添加值漓帅,有一個(gè)字段是自己增長(zhǎng)的锨亏,并且理論上這個(gè)值是不用插入的。

16).SQLite 注入(安卓數(shù)據(jù)目前沒(méi)有用到過(guò))
######作為了解內(nèi)容吧忙干!
注入通常在請(qǐng)求用戶輸入時(shí)發(fā)生器予,比如需要用戶輸入姓名,但用戶卻輸入了一個(gè) SQLite 語(yǔ)句捐迫,而這語(yǔ)句就會(huì)在不知不覺(jué)中在數(shù)據(jù)庫(kù)上運(yùn)行乾翔。
永遠(yuǎn)不要相信用戶提供的數(shù)據(jù),所以只處理通過(guò)驗(yàn)證的數(shù)據(jù)施戴,這項(xiàng)規(guī)則是通過(guò)模式匹配來(lái)完成的反浓。在下面的實(shí)例中,用戶名 username 被限制為字母數(shù)字字符或者下劃線赞哗,長(zhǎng)度必須在 8 到 20 個(gè)字符之間 - 請(qǐng)根據(jù)需要修改這些規(guī)則雷则。
if (preg_match("/^\w{8,20}$/", $_GET['username'], $matches)){
$db = new SQLiteDatabase('filename');
$result = @$db->query("SELECT * FROM users WHERE username=$matches[0]");
}else{
echo "username not accepted";
}
為了演示這個(gè)問(wèn)題,假設(shè)考慮此摘錄:To demonstrate the problem, consider this excerpt:
$name = "Qadir'; DELETE FROM users;";
@$db->query("SELECT * FROM users WHERE username='{$name}'");
函數(shù)調(diào)用是為了從用戶表中檢索 name 列與用戶指定的名稱相匹配的記錄肪笋。正常情況下月劈,$name 只包含字母數(shù)字字符或者空格,比如字符串 ilia藤乙。但在這里猜揪,向 $name 追加了一個(gè)全新的查詢,這個(gè)對(duì)數(shù)據(jù)庫(kù)的調(diào)用將會(huì)造成災(zāi)難性的問(wèn)題:注入的 DELETE 查詢會(huì)刪除 users 的所有記錄坛梁。
雖然已經(jīng)存在有不允許查詢堆疊或在單個(gè)函數(shù)調(diào)用中執(zhí)行多個(gè)查詢的數(shù)據(jù)庫(kù)接口而姐,如果嘗試堆疊查詢,則會(huì)調(diào)用失敗划咐,但 SQLite 和 PostgreSQL 里仍進(jìn)行堆疊查詢拴念,即執(zhí)行在一個(gè)字符串中提供的所有查詢钧萍,這會(huì)導(dǎo)致嚴(yán)重的安全問(wèn)題。
防止 SQL 注入
在腳本語(yǔ)言中丈莺,比如 PERL 和 PHP划煮,您可以巧妙地處理所有的轉(zhuǎn)義字符。編程語(yǔ)言 PHP 提供了字符串函數(shù) sqlite_escape_string() 來(lái)轉(zhuǎn)義對(duì)于 SQLite 來(lái)說(shuō)比較特殊的輸入字符缔俄。
if (get_magic_quotes_gpc())
{
$name = sqlite_escape_string($name);
}
$result = @$db->query("SELECT * FROM users WHERE username='{$name}'");
雖然編碼使得插入數(shù)據(jù)變得安全弛秋,但是它會(huì)呈現(xiàn)簡(jiǎn)單的文本比較,在查詢中俐载,對(duì)于包含二進(jìn)制數(shù)據(jù)的列蟹略,LIKE 子句是不可用的。
請(qǐng)注意遏佣,addslashes() 不應(yīng)該被用在 SQLite 查詢中引用字符串挖炬,它會(huì)在檢索數(shù)據(jù)時(shí)導(dǎo)致奇怪的結(jié)果。
17).SQLite Explain(解釋)
在 SQLite 語(yǔ)句之前状婶,可以使用 "EXPLAIN" 關(guān)鍵字或 "EXPLAIN QUERY PLAN" 短語(yǔ)意敛,用于描述表的細(xì)節(jié)。
如果省略了 EXPLAIN 關(guān)鍵字或短語(yǔ)膛虫,任何的修改都會(huì)引起 SQLite 語(yǔ)句的查詢行為草姻,并返回有關(guān) SQLite 語(yǔ)句如何操作的信息。
> 來(lái)自 EXPLAIN 和 EXPLAIN QUERY PLAN 的輸出只用于交互式分析和排除故障稍刀。
> 輸出格式的細(xì)節(jié)可能會(huì)隨著 SQLite 版本的不同而有所變化撩独。
> 應(yīng)用程序不應(yīng)該使用 EXPLAIN 或 EXPLAIN QUERY PLAN,因?yàn)槠浯_切的行為是可變的且只有部分會(huì)被記錄账月。
基本語(yǔ)法:
EXPLAIN 的語(yǔ)法如下:
EXPLAIN [SQLite Query]

EXPLAIN QUERY PLAN 的語(yǔ)法如下:
EXPLAIN  QUERY PLAN [SQLite Query]

實(shí)戰(zhàn)::
假設(shè) COMPANY 表有以下記錄:

ID | NAME | AGE | ADDRESS | SALARY
------|---- ---------- ---------- ---------- ----------
1 | Paul | 32 | California | 20000.0
2 | Allen | 25 | Texas | 15000.0
3 | Teddy | 23 | Norway | 20000.0
4 | Mark | 25 | Rich-Mond | 65000.0
5 | David | 27 | Texas | 85000.0
6 | Kim | 22 | South-Hall| 45000.0
7 | James | 24 | Houston | 10000.0

現(xiàn)在综膀,讓我們檢查 SELECT 語(yǔ)句中的 Explain 使用:
sqlite> EXPLAIN SELECT *  FROM COMPANY  WHERE Salary &gt= 20000;

這將產(chǎn)生以下結(jié)果:

addr | opcode | p1 | p2 | p3
-------|--- ---------- ---------- ---------- ----------
0 | Goto | 0 | 19
1 | Integer | 0 | 0
2 | OpenRead | 0 | 8
3 | SetNumColu | 0 | 5
4 | Rewind | 0 | 17
5 | Column | 0 | 4
6 | RealAffini | 0 | 0
7 | Integer | 20000 | 0
8 | Lt |357 | 16 | collseq(BI
9 | Rowid | 0 | 0
10 | Column | 0 | 1
11 | Column | 0 | 2
12 | Column | 0 | 3
13 | Column | 0 | 4
14 | RealAffini | 0 | 0
15 | Callback | 5 | 0
16 | Next | 0 | 5
17 | Close | 0 | 0
18 | Halt | 0 | 0
19 | Transactio | 0 | 0
20 | VerifyCook | 0 | 38
21 | Goto | 0 | 1
22 | Noop | 0 | 0

現(xiàn)在,讓我們檢查 SELECT 語(yǔ)句中的 Explain Query Plan 使用:
SQLite> EXPLAIN QUERY PLAN SELECT * FROM COMPANY WHERE Salary &gt= 20000;

order| from | detail
-------|--- ---------- -------------
0 | 0 | TABLE COMPANY
18).SQLite Vacuum(真空)
VACUUM 命令通過(guò)復(fù)制主數(shù)據(jù)庫(kù)中的內(nèi)容到一個(gè)臨時(shí)數(shù)據(jù)庫(kù)文件局齿,然后清空主數(shù)據(jù)庫(kù)剧劝,并從副本中重新載入原始的數(shù)據(jù)庫(kù)文件。這消除了空閑頁(yè)抓歼,把表中的數(shù)據(jù)排列為連續(xù)的担平,另外會(huì)清理數(shù)據(jù)庫(kù)文件結(jié)構(gòu)。
如果表中沒(méi)有明確的整型主鍵(INTEGER PRIMARY KEY)锭部,VACUUM 命令可能會(huì)改變表中條目的行 ID(ROWID)。VACUUM 命令只適用于主數(shù)據(jù)庫(kù)面褐,附加的數(shù)據(jù)庫(kù)文件是不可能使用 VACUUM 命令拌禾。
如果有一個(gè)活動(dòng)的事務(wù),VACUUM 命令就會(huì)失敗展哭。VACUUM 命令是一個(gè)用于內(nèi)存數(shù)據(jù)庫(kù)的任何操作湃窍。由于 VACUUM 命令從頭開(kāi)始重新創(chuàng)建數(shù)據(jù)庫(kù)文件闻蛀,所以 VACUUM 也可以用于修改許多數(shù)據(jù)庫(kù)特定的配置參數(shù)。

手動(dòng)VACUUM

下面是在命令提示符中對(duì)整個(gè)數(shù)據(jù)庫(kù)發(fā)出VACUUM命令的語(yǔ)法:
$sqlite3 database_name "VACUUM;"
您也可以在SQLite提示符中運(yùn)行VACUUM您市,如下所示:
sqlite > VACUUM;
您也可以在特定的表上運(yùn)行VACUUM觉痛,如下所示:
sqlite > VACUUM table_name;

自動(dòng)VACUUM(Auto-VACUUM)

SQLite 的 Auto-VACUUM 與 VACUUM 不大一樣,它只是把空閑頁(yè)移到數(shù)據(jù)庫(kù)末尾茵休,從而減小數(shù)據(jù)庫(kù)大小薪棒。通過(guò)這樣做,它可以明顯地把數(shù)據(jù)庫(kù)碎片化榕莺,而 VACUUM 則是反碎片化俐芯。所以 Auto-VACUUM 只會(huì)讓數(shù)據(jù)庫(kù)更小。
在 SQLite 提示符中钉鸯,您可以通過(guò)下面的編譯運(yùn)行吧史,啟用/禁用 SQLite 的 Auto-VACUUM:
sqlite> PRAGMA auto_vacuum = NONE;  -- 0 means disable auto vacuum
sqlite> PRAGMA auto_vacuum = INCREMENTAL;  -- 1 means enable incremental vacuum
sqlite> PRAGMA auto_vacuum = FULL;  -- 2 means enable full auto vacuum
您可以從命令提示符中運(yùn)行下面的命令來(lái)檢查 auto-vacuum 設(shè)置:
$sqlite3 database_name "PRAGMA auto_vacuum;"

19).SQLite 日期 & 時(shí)間
SQLite 支持以下五個(gè)日期和時(shí)間函數(shù):

序號(hào)| 函數(shù) | 實(shí)例
-----|
1 | date(timestring, modifier, modifier, ...) | 以 YYYY-MM-DD 格式返回日期。
2 | time(timestring, modifier, modifier, ...) | 以 HH:MM:SS 格式返回時(shí)間唠雕。
3 | datetime(timestring, modifier, modifier, ...) | 以 YYYY-MM-DD HH:MM:SS 格式返回贸营。
4 | julianday(timestring, modifier, modifier, ...) | 這將返回從格林尼治時(shí)間的公元前 4714 年 11 月 24 日正午算起的天數(shù)。
5 | strftime(format, timestring, modifier, modifier, ...)| 這將根據(jù)第一個(gè)參數(shù)指定的格式字符串返回格式化的日期岩睁。具體格式見(jiàn)下邊講解钞脂。

上述五個(gè)日期和時(shí)間函數(shù)把時(shí)間字符串作為參數(shù)。時(shí)間字符串后跟零個(gè)或多個(gè) modifier 修飾符笙僚。strftime() 函數(shù)也可以把格式字符串 format 作為其第一個(gè)參數(shù)芳肌。下面將為您詳細(xì)講解不同類型的時(shí)間字符串和修飾符。

時(shí)間字符串:
一個(gè)時(shí)間字符串可以采用下面任何一種格式:

序號(hào)| 時(shí)間字符串 | 實(shí)例
----|
1| YYYY-MM-DD | 2010-12-30
2| YYYY-MM-DD HH:MM | 2010-12-30 12:10
3| YYYY-MM-DD HH:MM:SS.SSS| 2010-12-30 12:10:04.100
4| MM-DD-YYYY HH:MM |30-12-2010 12:10
5| HH:MM | 12:10
6| YYYY-MM-DDTHH:MM | 2010-12-30 12:10
7| HH:MM:SS |12:10:01
8| YYYYMMDD HHMMSS | 20101230 121001
9| now | 2013-05-07
您可以使用 "T" 作為分隔日期和時(shí)間的文字字符肋层。

修飾符(Modifier)
時(shí)間字符串后邊可跟著零個(gè)或多個(gè)的修飾符亿笤,這將改變有上述五個(gè)函數(shù)返回的日期和/或時(shí)間。任何上述五大功能返回時(shí)間栋猖。修飾符應(yīng)從左到右使用净薛,下面列出了可在 SQLite 中使用的修飾符:
NNN days
NNN hours
NNN minutes
NNN.NNNN seconds
NNN months
NNN years
start of month
start of year
start of day
weekday N
unixepoch
localtime
utc

格式化
SQLite 提供了非常方便的函數(shù) strftime() 來(lái)格式化任何日期和時(shí)間。您可以使用以下的替換來(lái)格式化日期和時(shí)間:

替換 |描述
----|
%d |一月中的第幾天蒲拉,01-31
%f |帶小數(shù)部分的秒肃拜,SS.SSS
%H |小時(shí),00-23
%j |一年中的第幾天雌团,001-366
%J |儒略日數(shù)燃领,DDDD.DDDD
%m |月,00-12
%M |分锦援,00-59
%s |從 1970-01-01 算起的秒數(shù)
%S |秒猛蔽,00-59
%w| 一周中的第幾天,0-6 (0 is Sunday)
%W| 一年中的第幾周,01-53
%Y |年曼库,YYYY
%% | % symbol

實(shí)戰(zhàn)::

現(xiàn)在讓我們使用 SQLite 提示符嘗試不同的實(shí)例区岗。下面是計(jì)算當(dāng)前日期:

sqlite> SELECT date('now');
2013-05-07

下面是計(jì)算當(dāng)前月份的最后一天:

sqlite> SELECT date('now','start of month','+1 month','-1 day');
2013-05-31

下面是計(jì)算給定 UNIX 時(shí)間戳 1092941466 的日期和時(shí)間:

sqlite> SELECT datetime(1092941466, 'unixepoch');
2004-08-19 18:51:06

下面是計(jì)算給定 UNIX 時(shí)間戳 1092941466 相對(duì)本地時(shí)區(qū)的日期和時(shí)間:

sqlite> SELECT datetime(1092941466, 'unixepoch', 'localtime');
2004-08-19 11:51:06

下面是計(jì)算當(dāng)前的 UNIX 時(shí)間戳:

sqlite> SELECT strftime('%s','now');
1367926057

下面是計(jì)算美國(guó)"獨(dú)立宣言"簽署以來(lái)的天數(shù):
sqlite> SELECT julianday('now') - julianday('1776-07-04');
86504.4775830326

下面是計(jì)算從 2004 年某一特定時(shí)刻以來(lái)的秒數(shù):

sqlite> SELECT strftime('%s','now') - strftime('%s','2004-01-01 02:34:56');
295001572

下面是計(jì)算當(dāng)年 10 月的第一個(gè)星期二的日期:

sqlite> SELECT date('now','start of year','+9 months','weekday 2');
2013-10-01

下面是計(jì)算從 UNIX 紀(jì)元算起的以秒為單位的時(shí)間(類似 strftime('%s','now') ,不同的是這里有包括小數(shù)部分):

sqlite> SELECT (julianday('now') - 2440587.5)*86400.0;
1367926077.12598

在 UTC 與本地時(shí)間值之間進(jìn)行轉(zhuǎn)換毁枯,當(dāng)格式化日期時(shí)慈缔,使用 utc 或 localtime 修飾符,如下所示:

sqlite> SELECT time('12:00', 'localtime');
05:00:00
sqlite>  SELECT time('12:00', 'utc');
19:00:00

20).SQLite 常用函數(shù)

序號(hào) |函數(shù) & 描述
----|
1 | SQLite COUNT 函數(shù)
SQLite COUNT 聚集函數(shù)是用來(lái)計(jì)算一個(gè)數(shù)據(jù)庫(kù)表中的行數(shù)种玛。
2 | SQLite MAX 函數(shù)
SQLite MAX 聚合函數(shù)允許我們選擇某列的最大值藐鹤。
3 | SQLite MIN 函數(shù)
SQLite MIN 聚合函數(shù)允許我們選擇某列的最小值。
4 | SQLite AVG 函數(shù)
SQLite AVG 聚合函數(shù)計(jì)算某列的平均值蒂誉。
5 | SQLite SUM 函數(shù)
SQLite SUM 聚合函數(shù)允許為一個(gè)數(shù)值列計(jì)算總和教藻。
6 | SQLite RANDOM 函數(shù)
SQLite RANDOM 函數(shù)返回一個(gè)介于 -9223372036854775808 和 +9223372036854775807 之間的偽隨機(jī)整數(shù)。
7 | SQLite ABS 函數(shù)
SQLite ABS 函數(shù)返回?cái)?shù)值參數(shù)的絕對(duì)值右锨。
8 | SQLite UPPER 函數(shù)
SQLite UPPER 函數(shù)把字符串轉(zhuǎn)換為大寫字母括堤。
9 | SQLite LOWER 函數(shù)
SQLite LOWER 函數(shù)把字符串轉(zhuǎn)換為小寫字母。
10 | SQLite LENGTH 函數(shù)
SQLite LENGTH 函數(shù)返回字符串的長(zhǎng)度绍移。
11 | SQLite sqlite_version 函數(shù)
SQLite sqlite_version 函數(shù)返回 SQLite 庫(kù)的版本悄窃。

實(shí)戰(zhàn):
在我們開(kāi)始講解這些函數(shù)實(shí)例之前,先假設(shè) COMPANY 表有以下記錄:

ID | NAME | AGE | ADDRESS | SALARY
-----|----- ---------- ---------- ---------- ----------
1 | Paul | 32 | California | 20000.0
2 | Allen | 25 | Texas | 15000.0
3 | Teddy | 23 | Norway | 20000.0
4 | Mark | 25 | Rich-Mond | 65000.0
5 | David | 27 | Texas | 85000.0
6 | Kim | 22 | South-Hall |45000.0
7 | James | 24 | Houston | 10000.0

SQLite COUNT 函數(shù)

SQLite COUNT 聚集函數(shù)是用來(lái)計(jì)算一個(gè)數(shù)據(jù)庫(kù)表中的行數(shù)蹂窖。下面是實(shí)例:
sqlite> SELECT count(*) FROM COMPANY;
上面的 SQLite SQL 語(yǔ)句將產(chǎn)生以下結(jié)果:

count(*)
----------
7

SQLite MAX 函數(shù)

SQLite MAX 聚合函數(shù)允許我們選擇某列的最大值轧抗。下面是實(shí)例:
sqlite> SELECT max(salary) FROM COMPANY;
上面的 SQLite SQL 語(yǔ)句將產(chǎn)生以下結(jié)果:

max(salary)
-----------
85000.0

SQLite MIN 函數(shù)

SQLite MIN 聚合函數(shù)允許我們選擇某列的最小值。下面是實(shí)例:
sqlite> SELECT min(salary) FROM COMPANY;
上面的 SQLite SQL 語(yǔ)句將產(chǎn)生以下結(jié)果:
min(salary)
-----------
10000.0

SQLite AVG 函數(shù)

SQLite AVG 聚合函數(shù)計(jì)算某列的平均值瞬测。下面是實(shí)例:
sqlite> SELECT avg(salary) FROM COMPANY;
上面的 SQLite SQL 語(yǔ)句將產(chǎn)生以下結(jié)果:

avg(salary)
----------------
37142.8571428572

SQLite SUM 函數(shù)

SQLite SUM 聚合函數(shù)允許為一個(gè)數(shù)值列計(jì)算總和横媚。下面是實(shí)例:
sqlite> SELECT sum(salary) FROM COMPANY;
上面的 SQLite SQL 語(yǔ)句將產(chǎn)生以下結(jié)果:

sum(salary)
-----------
260000.0

SQLite RANDOM 函數(shù)

SQLite RANDOM 函數(shù)返回一個(gè)介于 -9223372036854775808 和 +9223372036854775807 之間的偽隨機(jī)整數(shù)。下面是實(shí)例:
sqlite> SELECT random() AS Random;
上面的 SQLite SQL 語(yǔ)句將產(chǎn)生以下結(jié)果:

Random
-------------------
5876796417670984050

SQLite ABS 函數(shù)

SQLite ABS 函數(shù)返回?cái)?shù)值參數(shù)的絕對(duì)值月趟。下面是實(shí)例:
sqlite> SELECT abs(5), abs(-15), abs(NULL), abs(0), abs("ABC");
上面的 SQLite SQL 語(yǔ)句將產(chǎn)生以下結(jié)果:
abs(5)      abs(-15)    abs(NULL)   abs(0)      abs("ABC")
----------  ----------  ----------  ----------  ----------
5           15                      0           0.0

SQLite UPPER 函數(shù)

SQLite UPPER 函數(shù)把字符串轉(zhuǎn)換為大寫字母灯蝴。下面是實(shí)例:
sqlite> SELECT upper(name) FROM COMPANY;
上面的 SQLite SQL 語(yǔ)句將產(chǎn)生以下結(jié)果:
upper(name)
-----------
PAUL
ALLEN
TEDDY
MARK
DAVID
KIM
JAMES

SQLite LOWER 函數(shù)

SQLite LOWER 函數(shù)把字符串轉(zhuǎn)換為小寫字母。下面是實(shí)例:
sqlite> SELECT lower(name) FROM COMPANY;
上面的 SQLite SQL 語(yǔ)句將產(chǎn)生以下結(jié)果:

lower(name)
-----------
paul
allen
teddy
mark
david
kim
james

SQLite LENGTH 函數(shù)

SQLite LENGTH 函數(shù)返回字符串的長(zhǎng)度孝宗。下面是實(shí)例:
sqlite> SELECT name, length(name) FROM COMPANY;
上面的 SQLite SQL 語(yǔ)句將產(chǎn)生以下結(jié)果:

NAME        length(name)
----------  ------------
Paul        4
Allen       5
Teddy       5
Mark        4
David       5
Kim         3
James       5

SQLite sqlite_version 函數(shù)

SQLite sqlite_version 函數(shù)返回 SQLite 庫(kù)的版本穷躁。下面是實(shí)例:
sqlite> SELECT sqlite_version() AS 'SQLite Version';
上面的 SQLite SQL 語(yǔ)句將產(chǎn)生以下結(jié)果:
SQLite Version
--------------
3.6.20
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市因妇,隨后出現(xiàn)的幾起案子问潭,更是在濱河造成了極大的恐慌,老刑警劉巖婚被,帶你破解...
    沈念sama閱讀 218,858評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件狡忙,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡址芯,警方通過(guò)查閱死者的電腦和手機(jī)去枷,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人删顶,你說(shuō)我怎么就攤上這事∈缋龋” “怎么了逗余?”我有些...
    開(kāi)封第一講書人閱讀 165,282評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)季惩。 經(jīng)常有香客問(wèn)我录粱,道長(zhǎng),這世上最難降的妖魔是什么画拾? 我笑而不...
    開(kāi)封第一講書人閱讀 58,842評(píng)論 1 295
  • 正文 為了忘掉前任啥繁,我火速辦了婚禮,結(jié)果婚禮上青抛,老公的妹妹穿的比我還像新娘旗闽。我一直安慰自己,他們只是感情好蜜另,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,857評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布适室。 她就那樣靜靜地躺著,像睡著了一般举瑰。 火紅的嫁衣襯著肌膚如雪捣辆。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 51,679評(píng)論 1 305
  • 那天此迅,我揣著相機(jī)與錄音汽畴,去河邊找鬼。 笑死耸序,一個(gè)胖子當(dāng)著我的面吹牛忍些,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播佑吝,決...
    沈念sama閱讀 40,406評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼坐昙,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了芋忿?” 一聲冷哼從身側(cè)響起炸客,我...
    開(kāi)封第一講書人閱讀 39,311評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎戈钢,沒(méi)想到半個(gè)月后痹仙,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,767評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡殉了,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年开仰,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,090評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡众弓,死狀恐怖恩溅,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情谓娃,我是刑警寧澤脚乡,帶...
    沈念sama閱讀 35,785評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站滨达,受9級(jí)特大地震影響奶稠,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜捡遍,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,420評(píng)論 3 331
  • 文/蒙蒙 一锌订、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧画株,春花似錦辆飘、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,988評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至良拼,卻和暖如春战得,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背庸推。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,101評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工常侦, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人贬媒。 一個(gè)月前我還...
    沈念sama閱讀 48,298評(píng)論 3 372
  • 正文 我出身青樓聋亡,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親际乘。 傳聞我的和親對(duì)象是個(gè)殘疾皇子坡倔,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,033評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容