- SQLite
- 为什么使用SQLite?
- SQLite 命令
- SQLite 安装
- SQLite 命令
- SQLite 语法
- SQLite 语句
- SQLite 数据类型
- SQLite 特殊运算符
- SQLite SQL
- 高级用法
SQLite
SQLite 是一个软件库,实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎,其源代码不受版权限制。
SQLite是一个进程内的库,但不是一个独立的进程,可以按应用程序的需求进行静态或动态连接,SQLite直接访问其存储文件。
为什么使用SQLite?
不需要一个单独的服务器进程或操作的系统(无服务器的)。
SQLite 不需要配置,这意味着不需要安装或管理。
一个完整的 SQLite 数据库是存储在一个单一的跨平台的磁盘文件。
SQLite 是非常小的,是轻量级的,完全配置时小于 400KiB,省略可选功能配置时小于250KiB。
SQLite 是自给自足的,这意味着不需要任何外部的依赖。
SQLite 事务是完全兼容 ACID 的,允许从多个进程或线程安全访问。
SQLite 支持 SQL92(SQL2)标准的大多数查询语言的功能。
SQLite 使用 ANSI-C 编写的,并提供了简单和易于使用的 API。
SQLite 可在 UNIX(Linux, Mac OS-X, Android, iOS)和 Windows(Win32, WinCE, WinRT)中运行。
SQLite 命令
与关系数据库进行交互的标准 SQLite 命令类似于 SQL。命令包括 CREATE、SELECT、INSERT、UPDATE、DELETE 和 DROP。这些命令基于它们的操作性质可分为以下几种:
DDL-数据定义语言
CREATE : 创建一个新的表,一个表的视图,或者数据库中的其他对象。
ALTER : 修改数据库中的某个已有的数据库对象,比如一个表。
DROP : 删除整个表,或者表的视图,或者数据库中的其他对象。
DML-数据操作语言
INSERT : 创建一条记录。
UPDATE : 修改记录。
DELETE : 删除记录。
DQL-数据查询语言
SELECT : 从一个或多个表中检索某些记录。
SQLite 安装
在 Windows 上安装 SQLite
访问 SQLite 下载页面http://www.sqlite.org/download.html,从 Windows 区下载预编译的二进制文件。
您需要下载 sqlite-tools-win32-.zip 和 sqlite-dll-win32-.zip 压缩文件。
创建文件夹 C:\sqlite,并在此文件夹下解压上面两个压缩文件,将得到 sqlite3.def、sqlite3.dll 和 sqlite3.exe 文件。
添加 C:\sqlite 到 PATH 环境变量,最后在命令提示符下,使用 sqlite3 命令,将显示如下结果
C:\>sqlite3
SQLite version 3.7.15.2 2013-01-09 11:53:05
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite>
在 Linux 上安装 SQLite
目前,几乎所有版本的 Linux 操作系统都附带 SQLite。所以,只要使用下面的命令来检查您的机器上是否已经安装了 SQLite。
$ sqlite3
SQLite version 3.7.15.2 2013-01-09 11:53:05
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite>
如果没有看到上面的结果,那么就意味着没有在 Linux 机器上安装 SQLite。因此,让我们按照下面的步骤安装 SQLite:
请访问 SQLite 下载页面,从源代码区下载 sqlite-autoconf-*.tar.gz。
步骤如下:
$ tar xvzf sqlite-autoconf-3071502.tar.gz
$ cd sqlite-autoconf-3071502
$ ./configure --prefix=/usr/local
$ make
$ make install
上述步骤将在 Linux 机器上安装 SQLite,您可以按照上述讲解的进行验证。
SQLite 命令
让我们在命令提示符下键入一个简单的 sqlite3 命令,在 SQLite 命令提示符下,您可以使用各种 SQLite 命令。
$ sqlite3
SQLite version 3.3.6
Enter ".help" for instructions
sqlite>
如需获取可用的点命令的清单,可以在任何时候输入 “.help”。例如:
sqlite>.help
让我们尝试使用 .show 命令,来查看 SQLite 命令提示符的默认设置。
sqlite>.show
echo: off
explain: off
headers: off
mode: column
nullvalue: ""
output: stdout
separator: "|"
width:
sqlite>
主表中保存数据库表的关键信息,并把它命名为 sqlite_master。如要查看表概要,可按如下操作:
sqlite>.schema sqlite_master
//将产生如下:
CREATE TABLE sqlite_master (
type text,
name text,
tbl_name text,
rootpage integer,
sql text
);
SQLite 语法
-
大小写敏感性
有个重要的点值得注意,SQLite 是不区分大小写的,但也有一些命令是大小写敏感的,比如 GLOB 和 glob 在 SQLite 的语句中有不同的含义。 -
注释
SQLite 注释是附加的注释,可以在 SQLite 代码中添加注释以增加其可读性,他们可以出现在任何空白处,包括在表达式内和其他 SQL 语句的中间,但它们不能嵌套。
SQL 注释以两个连续的 “-” 字符(ASCII 0x2d)开始,并扩展至下一个换行符(ASCII 0x0a)或直到输入结束,以先到者为准。
您也可以使用 C 风格的注释,以 “/" 开始,并扩展至下一个 "/” 字符对或直到输入结束,以先到者为准。SQLite的注释可以跨越多行。
sqlite>.help -- 这是一个简单的注释
SQLite 语句
所有的 SQLite 语句可以以任何关键字开始,如 SELECT、INSERT、UPDATE、DELETE、ALTER、DROP 等,所有的语句以分号(;)结束。
SQLite ANALYZE 语句:
ANALYZE;
--or
ANALYZE database_name;
--or
ANALYZE database_name.table_name;
SQLite AND/OR 子句:
SELECT column1, column2....columnN
FROM table_name
WHERE CONDITION-1 {AND|OR} CONDITION-2;
SQLite ALTER TABLE 语句:
ALTER TABLE table_name ADD COLUMN column_def...;
SQLite ALTER TABLE 语句(Rename):
ALTER TABLE table_name RENAME TO new_table_name;
SQLite ATTACH DATABASE 语句:
ATTACH DATABASE 'DatabaseName' As 'Alias-Name'; --附加
/*
假设这样一种情况,当在同一时间有多个数据库可用,您想使用其中的任何一个。SQLite 的 ATTACH DTABASE 语句是用来选择一个特定的数据库,使用该命令后,所有的 SQLite 语句将在附加的数据库下执行。
如果数据库尚未被创建,上面的命令将创建一个数据库,如果数据库已存在,则把数据库文件名称与逻辑数据库 'Alias-Name' 绑定在一起。
*/
SQLite BEGIN TRANSACTION 语句:
BEGIN;
--or
BEGIN EXCLUSIVE TRANSACTION; --开始执行事务
SQLite BETWEEN 子句:
SELECT column1, column2....columnN
FROM table_name
WHERE column_name BETWEEN val-1 AND val-2;
SQLite COMMIT 语句:
COMMIT;
SQLite CREATE INDEX 语句:
CREATE INDEX index_name --创建索引
ON table_name ( column_name COLLATE NOCASE ); --校对规则为NOCASE,无
SQLite CREATE UNIQUE INDEX 语句:
CREATE UNIQUE INDEX index_name --创建单一索引
ON table_name (column1, column2,...columnN);
SQLite CREATE TABLE 语句:
CREATE TABLE table_name(
column1 datatype,
column2 datatype,
column3 datatype,
.....
columnN datatype,
PRIMARY KEY( one or more columns )
);
SQLite CREATE TRIGGER 语句:
CREATE TRIGGER database_name.trigger_name --创建触发器,数据库名.触发器名
BEFORE INSERT ON table_name FOR EACH ROW
BEGIN
stmt1;
stmt2;
....
END;
SQLite CREATE VIEW 语句:
CREATE VIEW database_name.view_name AS --创建一个视图,数据库名.视图名
SELECT statement....;
SQLite CREATE VIRTUAL TABLE 语句:
CREATE VIRTUAL TABLE database_name.table_name USING weblog( access.log ); --创建一个虚表
--or
CREATE VIRTUAL TABLE database_name.table_name USING fts3( );
SQLite COMMIT TRANSACTION 语句:
COMMIT;
SQLite COUNT 子句:
SELECT COUNT(column_name)
FROM table_name
WHERE CONDITION;
SQLite DELETE 语句:
DELETE FROM table_name
WHERE {CONDITION};
SQLite DETACH DATABASE 语句:
DETACH DATABASE 'Alias-Name'; --分离
/*
SQLite的的DETACH DTABASE语句是用来分离和游离命名数据库从一个数据库连接,先前连接使用ATTACH语句。如果同一个数据库文件已经连接使用多个别名,然后分离命令将断开只给定的名称而其余名称仍将继续。
无法分离主main或临时temp数据库。*如果数据库是在内存中或临时数据库,该数据库将被摧毁,内容将会丢失。
*/
SQLite DISTINCT 子句:
SELECT DISTINCT column1, column2....columnN --取消重复项
FROM table_name;
SQLite DROP INDEX 语句:
DROP INDEX database_name.index_name;
SQLite DROP TABLE 语句:
DROP TABLE database_name.table_name;
SQLite DROP VIEW 语句:
DROP VIEW view_name;
SQLite DROP TRIGGER 语句:
DROP TRIGGER trigger_name
SQLite EXISTS 子句:
SELECT column1, column2....columnN
FROM table_name
WHERE column_name EXISTS (SELECT * FROM table_name ); --EXISTS是判断是否存在,和in类似,但效率要比in高
SQLite EXPLAIN 语句:
EXPLAIN INSERT statement...; --用于描述表的细节
--or
EXPLAIN QUERY PLAN SELECT statement...; --按选择描述查询计划
SQLite GLOB 子句:
SELECT column1, column2....columnN
FROM table_name
WHERE column_name GLOB { PATTERN }; --用来匹配通配符指定模式的文本值
SQLite GROUP BY 子句:
SELECT SUM(column_name)
FROM table_name
WHERE CONDITION
GROUP BY column_name; --分组筛选
SQLite HAVING 子句:
SELECT SUM(column_name)
FROM table_name
WHERE CONDITION
GROUP BY column_name
HAVING (arithematic function condition); --允许指定条件来过滤将出现在最终结果中的分组结果
SQLite INSERT INTO 语句:
INSERT INTO table_name( column1, column2....columnN)
VALUES ( value1, value2....valueN);
SQLite IN 子句:
SELECT column1, column2....columnN
FROM table_name
WHERE column_name IN (val-1, val-2,...val-N);
SQLite Like 子句:
SELECT column1, column2....columnN
FROM table_name
WHERE column_name LIKE { PATTERN }; --用来匹配通配符指定模式的文本值
SQLite NOT IN 子句:
SELECT column1, column2....columnN
FROM table_name
WHERE column_name NOT IN (val-1, val-2,...val-N);
SQLite ORDER BY 子句:
SELECT column1, column2....columnN
FROM table_name
WHERE CONDITION
ORDER BY column_name {ASC|DESC}; --排序规则
SQLite PRAGMA 语句:
PRAGMA pragma_name; 控制各种环境变量和状态标志
--For example:
PRAGMA page_size;
PRAGMA cache_size = 1024;
PRAGMA table_info(table_name);
SQLite RELEASE SAVEPOINT 语句:
RELEASE savepoint_name; --释放保存点
/*
需要对执行命令后已经更改的记录进行回滚时可使用savepoint来实现。
例如当执行UPDATE命令时会创建一个隐式的savepoint来记录事务的状态,如果命令执行时出现违反约束的冲突,事务将根据这个savepoint来回退。
*/
SQLite REINDEX 语句:
REINDEX collation_name; --重新创建索引
REINDEX database_name.index_name;
REINDEX database_name.table_name;
SQLite ROLLBACK 语句:
ROLLBACK;
--or
ROLLBACK TO SAVEPOINT savepoint_name; --回滚
SQLite SAVEPOINT 语句:
SAVEPOINT savepoint_name;
SQLite SELECT 语句:
SELECT column1, column2....columnN
FROM table_name;
SQLite UPDATE 语句:
UPDATE table_name
SET column1 = value1, column2 = value2....columnN=valueN
[ WHERE CONDITION ];
SQLite VACUUM 语句:
VACUUM;
/*
VACUUM 命令通过复制主数据库中的内容到一个临时数据库文件,然后清空主数据库,并从副本中重新载入原始的数据库文件。
这消除了空闲页,把表中的数据排列为连续的,另外会清理数据库文件结构。
*/
SQLite WHERE 子句:
SELECT column1, column2....columnN
FROM table_name
WHERE CONDITION;
SQLite 数据类型
-
SQLite 存储类
每个存储在 SQLite 数据库中的值都具有以下存储类之一: -
SQLite 亲和(Affinity)类型
SQLite支持列的亲和类型概念。任何列仍然可以存储任何类型的数据,当数据插入时,该字段的数据将会优先采用亲缘类型作为该值的存储方式。SQLite目前的版本支持以下五种亲缘类型: -
SQLite亲和类型(Affinity)及类型名称
下表列出了当创建 SQLite3 表时可使用的各种数据类型名称,同时也显示了相应的亲和类型:
-
Boolean 数据类型
SQLite 没有单独的 Boolean 存储类。相反,布尔值被存储为整数 0(false)和 1(true)。 -
Date 与 Time 数据类型
SQLite 没有一个单独的用于存储日期和/或时间的存储类,但 SQLite 能够把日期和时间存储为 TEXT、REAL 或 INTEGER 值。
SQLite 特殊运算符
ADN :AND 运算符意为在一个 SQL 语句的 WHERE 子句中的多个条件同时成立。
OR : OR运算符意为在一个 SQL 语句的 WHERE 子句中的多个条件至少一个成立。
BETWEEN : BETWEEN 运算符用于在给定最小值和最大值范围内的一系列值中搜索值。
UNIQUE :UNIQUE运算符搜索指定表中的每一行,确保其唯一性。
EXISTS :EXISTS 运算符用于在满足一定条件的指定表中搜索某行的存在,其执行效率比IN高。
IN :IN运算符用于把某个值与一系列指定列表的值进行比较。
NOT IN :IN运算符的对立面,用于把某个值与不在一系列指定列表的值进行比较。
IS :IS运算符与 = 相似。
IS NOT :IS NOT运算符与 != 相似。
IS NULL :IS NULL运算符用于把某个值与NULL值进行比较。
LIKE :LIKE 运算符用于把某个值与使用通配符运算符的相似值进行比较。
GLOB :GLOB 运算符用于把某个值与使用通配符运算符的相似值进行比较。GLOB与LIKE 不同之处在于,它是大小写敏感的。
NOT :NOT 运算符是否定运算符,其用于其他逻辑运算符的对立面,比如 NOT EXISTS、NOT BETWEEN、NOT IN等等。
|| :连接两个不同的字符串,得到一个新的字符串。
SQLite SQL
--创建数据库
$sqlite3 DatabaseName.db
--列出所有数据库
sqlite>.databases
--退出sqlite 提示符
sqlite>.quit
--导出到文本
$sqlite3 testDB.db .dump > testDB.sql
--恢复到数据库
$sqlite3 testDB.db < testDB.sql
--附加数据库
sqlite> ATTACH DATABASE 'testDB.db' as 'TEST';
/*
假设这样一种情况,当在同一时间有多个数据库可用,您想使用其中的任何一个。SQLite 的 ATTACH DATABASE 语句是用来选择一个特定的数据库,使用该命令后,所有的 SQLite 语句将在附加的数据库下执行。
如果数据库尚未被创建,上面的命令将创建一个数据库,如果数据库已存在,则把数据库文件名称与逻辑数据库 'Alias-Name' 绑定在一起。
*/
--分离数据库
sqlite> DETACH DATABASE 'currentDB'; --如果检查当前附加的数据库,您会发现,testDB.db 仍与 'test' 和 'main' 保持连接。
/*
SQLite的 DETACH DTABASE 语句是用来把命名数据库从一个数据库连接分离和游离出来,连接是之前使用 ATTACH 语句附加的。如果同一个数据库文件已经被附加上多个别名,DETACH 命令将只断开给定名称的连接,而其余的仍然有效。您无法分离 main 或 temp 数据库。
如果数据库是在内存中或者是临时数据库,则该数据库将被摧毁,且内容将会丢失。
*/
--创建表
sqlite> CREATE TABLE COMPANY(
ID INT PRIMARY KEY NOT NULL,
NAME TEXT NOT NULL,
AGE INT NOT NULL,
ADDRESS CHAR(50),
SALARY REAL
);
--列出当前数据库的所有表
qlite>.tables
--查看表的详细信息
sqlite>.schema user
--删除表
sqlite> DROP TABLE user;
--Insert语句
INSERT INTO TABLE_NAME [(column1, column2, column3,...columnN)]
VALUES (value1, value2, value3,...valueN);
--Select语句
SELECT * FROM TABLE_NAME;
select column1, column2, column3 FROM TABLE_NAME;
SELECT tbl_name FROM sqlite_master WHERE type = 'table'; --列出所有数据库中的表,常用于点命令不可用的情况
--Where子句
SELECT column1, column2, columnN
FROM table_name
WHERE [condition]; --conditon和算数运算符、比较运算符、逻辑运算符和位运算符相关
--Updata语句
UPDATE table_name
SET column1 = value1, column2 = value2...., columnN = valueN
WHERE [condition]; --通过where条件选定行,否则所有的行都会被更新
--Delete语句
DELETE FROM table_name
WHERE [condition];
--Like子句
SELECT column_list FROM table_name --百分号(%)代表零到多个数字或字符。下划线(_)代表一个数字或字符
WHERE SALARY LIKE '200%'; --查找以 200 开头的任意值
WHERE SALARY LIKE '%200%'; --查找任意位置包含 200 的任意值
WHERE SALARY LIKE '_00%'; --查找第二位和第三位为 00 的任意值
WHERE SALARY LIKE '2_%_%'; --查找以 2 开头,且长度至少为 3 个字符的任意值
WHERE SALARY LIKE '%2'; --查找以 2 结尾的任意值
WHERE SALARY LIKE '_2%3'; --查找第二位为 2,且以 3 结尾的任意值
WHERE SALARY LIKE '2___3'; --查找长度为 5 位数,且以 2 开头以 3 结尾的任意值
--GLOB子句
SELECT FROM table_name --星号(*)代表零个到多个数字或字符。问号(?)代表一个数字或字符。GLOB大小写敏感。
WHERE SALARY GLOB '200*' --查找以 200 开头的任意值
WHERE SALARY GLOB '*200*' --查找任意位置包含 200 的任意值
WHERE SALARY GLOB '?00*' --查找第二位和第三位为 00 的任意值
WHERE SALARY GLOB '2??' --查找以 2 开头,且长度至少为 3 个字符的任意值
WHERE SALARY GLOB '*2' --查找以 2 结尾的任意值
WHERE SALARY GLOB '?2*3' --查找第二位为 2,且以 3 结尾的任意值
WHERE SALARY GLOB '2???3' --查找长度为 5 位数,且以 2 开头以 3 结尾的任意值
--Limit子句
SELECT column1, column2, columnN
FROM table_name
LIMIT [no of rows] OFFSET [row num]; --Limit后限制返回的行数,Offset后为需要偏移的行数
--Order By
SELECT column-list
FROM table_name
[WHERE condition]
[ORDER BY column1, column2, .. columnN] [ASC | DESC];
--Group By
SELECT column-list
FROM table_name
WHERE [ conditions ]
GROUP BY column1, column2....columnN
ORDER BY column1, column2....columnN;
--Having子句
SELECT column1, column2
FROM table1, table2
WHERE [ conditions ]
GROUP BY column1, column2 -- HAVING 子句在由 GROUP BY 子句创建的分组上设置条件
HAVING [ conditions ]
ORDER BY column1, column2;
--Distinct关键字
SELECT DISTINCT column1, column2,.....columnN -- 与SELECT语句一起使用,来消除所有重复的记录,并只获取唯一的记录
FROM table_name
WHERE [condition]
高级用法
SQLite PRAGMA
SQLite 的 PRAGMA 命令是一个特殊的命令,可以用在 SQLite 环境内控制各种环境变量和状态标志。一个 PRAGMA 值可以被读取,也可以根据需求进行设置。
pragma_name;
PRAGMA pragma_name = value; --设置一个新值
- auto_vacuum Pragma
获取或设置auto-vacuum模式。
PRAGMA [database.]auto_vacuum;
PRAGMA [database.]auto_vacuum = mode; --mode可为0或NONE,禁止Auto-vacuum,默认模式; 1或FULL,启用Auto-vacuum,,是全自动的,2或INCREAMENTAL,启用Auto-vacuum,任何时候可以使用 incremental_vacuum pragma 进行覆盖。
- cache_size_Pragma
cache_size Pragma 可获取或暂时设置在内存中页面缓存的最大尺寸。
PRAGMA [database.]cache_size;
PRAGMA [database.]cache_size = pages; --默认大小为2000页,最小尺寸为10页
- case_sensitive_like Pragma
控制内置的 LIKE 表达式的大小写敏感度。默认情况下,该 Pragma 为 false,这意味着,内置的 LIKE 操作符忽略字母的大小写。
PRAGMA case_sensitive_like = [true|false]; --目前没有办法查询该Pragma的当前状态
- count_changes Pragma
count_changes Pragma 获取或设置数据操作语句的返回值,如 INSERT、UPDATE 和 DELETE。
默认情况下,该 Pragma 为 false,这些语句不返回任何东西。如果设置为 true,每个所提到的语句将返回一个单行单列的表,由一个单一的整数值组成,该整数表示操作影响的行。
PRAGMA count_changes;
PRAGMA count_changes = [true|false];
- database_list Pragma
database_list Pragma 将用于列出了所有的数据库连接。
该 Pragma 将返回一个单行三列的表格,每当打开或附加数据库时,会给出数据库中的序列号,它的名称和相关的文件。
PRAGMA database_list;
- encoding Pragma
encoding Pragma 控制字符串如何编码及存储在数据库文件中。
PRAGMA encoding;
PRAGMA encoding = format; --格式值可以是 UTF-8、UTF-16le 或 UTF-16be 之一。
- freelist_count Pragma
freelist_count Pragma 返回一个整数,表示当前被标记为免费和可用的数据库页数。
PRAGMA [database.]freelist_count;
- index_info Pragma
index_info Pragma 返回关于数据库索引的信息。结果集将为 每个包含在给出列序列的索引、表格内的列索引、列名称的列 显示一行。
PRAGMA [database.]index_info( index_name );
- index_list Pragma
index_list Pragma 列出所有与表相关联的索引。结果集将为 每个给出列序列的索引、索引名称、表示索引是否唯一的标识 显示一行。
PRAGMA [database.]index_list( table_name );
- journal_mode Pragma
journal_mode Pragma 获取或设置控制日志文件如何存储和处理的日志模式。
PRAGMA journal_mode;
PRAGMA journal_mode = mode;
PRAGMA database.journal_mode;
PRAGMA database.journal_mode = mode;
/*
DELETE : 默认模式。在该模式下,在事务结束时,日志文件将被删除。
TRUNCATE : 日志文件被截断为零字节长度。
PERSIST : 日志文件被留在原地,但头部被重写,表明日志不再有效。
MEMORY : 日志记录保留在内存中,而不是磁盘上。
OFF : 不保留任何日志记录。
*/
- max_page_count Pragma
max_page_count Pragma 为数据库获取或设置允许的最大页数。
默认值是 1,073,741,823,这是一千兆的页面,即如果默认 1 KB 的页面大小,那么数据库中增长起来的一个兆字节。
PRAGMA [database.]max_page_count;
PRAGMA [database.]max_page_count = max_page;
- page_count Pragma
page_count Pragma 返回当前数据库中的网页数量。
PRAGMA [database.]page_count;
- page_size Pragma
page_size Pragma 获取或设置数据库页面的大小。
默认情况下,允许的尺寸是 512、1024、2048、4096、8192、16384、32768 字节。改变现有数据库页面大小的唯一方法就是设置页面大小,然后立即 VACUUM 该数据库。
PRAGMA [database.]page_size;
PRAGMA [database.]page_size = bytes;
- parser_trace Pragma
parser_trace Pragma 随着 SQL 解析器解析 SQL 命令来控制打印的调试状态。
默认情况下,它被设置为 false,但设置为 true 时则启用,此时 SQL 解析器会随着它解析 SQL 命令来打印出它的状态。
PRAGMA parser_trace = [true|false];
- recursive_triggers Pragma
recursive_triggers Pragma 获取或设置递归触发器功能。如果未启用递归触发器,一个触发动作将不会触发另一个触发。
PRAGMA recursive_triggers;
PRAGMA recursive_triggers = [true|false];
- schema_version Pragma
schema_version Pragma 获取或设置存储在数据库头中的的架构版本值。
PRAGMA [database.]schema_version; --32位有符号整数值,用来跟踪架构的变化,当一个架构改变命令被执行(比如 CREATE... 或 DROP...),这个值会递增
PRAGMA [database.]schema_version = number;
- secure_delete Pragma
secure_delete Pragma 用来控制内容是如何从数据库中删除。
安全删除标志的默认值通常是关闭的,但是这是可以通过 SQLITE_SECURE_DELETE 构建选项来改变的。
PRAGMA secure_delete;
PRAGMA secure_delete = [true|false];
PRAGMA database.secure_delete;
PRAGMA database.secure_delete = [true|false];
- sql_trace Pragma
sql_trace Pragma 用于把 SQL 跟踪结果转储到屏幕上。SQLite 必须通过 SQLITE_DEBUG 指令来编译要引用的该 Pragma。
PRAGMA sql_trace;
PRAGMA sql_trace = [true|false];
- synchronous Pragma
synchronous Pragma 获取或设置当前磁盘的同步模式,该模式控制积极的 SQLite 如何将数据写入物理存储。
PRAGMA [database.]synchronous;
PRAGMA [database.]synchronous = mode;
/*
SQLite 支持下列同步模式:
0 或 OFF : 不进行同步。
1 或 NORMAL : 在关键的磁盘操作的每个序列后同步。
2 或 FULL : 在每个关键的磁盘操作后同步。
*/
- temp_store Pragma
temp_store Pragma 获取或设置临时数据库文件所使用的存储模式。:
PRAGMA temp_store;
PRAGMA temp_store = mode;
/*
SQLite 支持下列存储模式:
0 或 DEFAULT : 默认使用编译时的模式。通常是 FILE。
1 或 FILE : 使用基于文件的存储。
2 或 MEMORY : 使用基于内存的存储。
*/
- temp_store_directory Pragma
temp_store_directory Pragma 获取或设置用于临时数据库文件的位置。
PRAGMA temp_store_directory;
PRAGMA temp_store_directory = 'directory_path';
- user_version Pragma
user_version Pragma 获取或设置存储在数据库头的用户自定义的版本值。
PRAGMA [database.]user_version; --32位的有符号整数值,可以由开发人员设置,用于版本跟踪的目的
PRAGMA [database.]user_version = number;
- writable_schema Pragma
writable_schema Pragma 获取或设置是否能够修改系统表。
如果设置了该 Pragma,则表以 sqlite_ 开始,可以创建和修改,包括 sqlite_master 表。使用该 Pragma 时要注意,因为它可能导致整个数据库损坏。
PRAGMA writable_schema;
PRAGMA writable_schema = [true|false];
SQLite 约束
约束是在表的数据列上强制执行的规则。这些是用来限制可以插入到表中的数据类型。这确保了数据库中数据的准确性和可靠性。
约束可以是列级或表级。列级约束仅适用于列,表级约束被应用到整个表。
PRIMARY KEY 约束:唯一标识数据库表中的各行/记录。
NOT NULL 约束:确保某列不能有 NULL 值。
DEFAULT 约束:当某列没有指定值时,为该列提供默认值。
UNIQUE 约束:确保某列中的所有值是不同的。其实SQLite并不直接支持Unique约束,而是自动创建相应的索引
CHECK 约束:CHECK 约束确保某列中的所有值满足一定条件。
SQLite 连接
SQLite 的 Join 子句用于结合两个或多个数据库中表的记录。JOIN 是一种通过共同值来结合两个表中字段的手段。
SQL 定义了三种主要类型的连接:交叉连接、内连接、外连接
- 交叉连接 - CROSS JOIN
交叉连接(CROSS JOIN)把第一个表的每一行与第二个表的每一行进行匹配。如果两个输入表分别有 x 和 y 行,则结果表有 x*y 行。由于交叉连接有可能产生非常大的表,使用时必须谨慎,只在适当的时候使用。
交叉连接的操作,它们都返回被连接的两个表所有数据行的笛卡尔积,返回到的数据行数等于第一个表中符合查询条件的数据行数乘以第二个表中符合查询条件的数据行数。
SELECT ... FROM table1 CROSS JOIN table2
- 内连接 - INNER JOIN
内连接(INNER JOIN)根据连接谓词结合两个表(table1 和 table2)的列值来创建一个新的结果表。查询会把 table1 中的每一行与 table2 中的每一行进行比较,找到所有满足连接谓词的行的匹配对。当满足连接谓词时,A 和 B 行的每个匹配对的列值会合并成一个结果行。
内连接(INNER JOIN)是最常见的连接类型,是默认的连接类型。INNER 关键字是可选的。
SELECT ... FROM table1 [INNER] JOIN table2 ON conditional_expression ...
SELECT ... FROM table1 JOIN table2 USING ( column1 ,... ) ...
SELECT ... FROM table1 NATURAL JOIN table2... --自然连接(NATURAL JOIN)类似于 JOIN...USING,只是它会自动测试存在两个表中的每一列的值之间相等值
- 外连接 - OUTER JOIN
外连接(OUTER JOIN)是内连接(INNER JOIN)的扩展。虽然 SQL 标准定义了三种类型的外连接:LEFT、RIGHT、FULL,但 SQLite 只支持 左外连接(LEFT OUTER JOIN)。
外连接(OUTER JOIN)声明条件的方法与内连接(INNER JOIN)是相同的,使用 ON、USING 或 NATURAL 关键字来表达。
最初的结果表以相同的方式进行计算。一旦主连接计算完成,外连接(OUTER JOIN)将从一个或两个表中任何未连接的行合并进来,外连接的列使用 NULL 值,将它们附加到结果表中。
SELECT ... FROM table1 LEFT OUTER JOIN table2 ON conditional_expression ...
SELECT ... FROM table1 LEFT OUTER JOIN table2 USING ( column1 ,... ) ...
SQLite Unions子句
SQLite的 UNION 子句/运算符用于合并两个或多个 SELECT 语句的结果,不返回任何重复的行。
为了使用 UNION,每个 SELECT 被选择的列数必须是相同的,相同数目的列表达式,相同的数据类型,并确保它们有相同的顺序,但它们不必具有相同的长度。
UNION ALL 运算符用于结合两个 SELECT 语句的结果,包括重复行。适用于 UNION 的规则同样适用于 UNION ALL 运算符。
SELECT column1 [, column2 ]
FROM table1 [, table2 ]
[WHERE condition]
UNION / UNION ALL
SELECT column1 [, column2 ]
FROM table1 [, table2 ]
[WHERE condition]
SQLite 别名
您可以暂时把表或列重命名为另一个名字,这被称为别名。使用表别名是指在一个特定的 SQLite 语句中重命名表。重命名是临时的改变,在数据库中实际的表的名称不会改变。
列别名用来为某个特定的 SQLite 语句重命名表中的列。
--表别名的基本语法如下:
SELECT column1, column2....
FROM table_name AS alias_name
WHERE [condition];
--列别名的基本语法如下:
SELECT column_name AS alias_name
FROM table_name
WHERE [condition];
SQLite 触发器(Trigger)
SQLite 触发器(Trigger)是数据库的回调函数,它会在指定的数据库事件发生时自动执行/调用。以下是关于 SQLite 的触发器(Trigger)的要点:
-
SQLite 的触发器(Trigger)可以指定在特定的数据库表发生 DELETE、INSERT 或 UPDATE 时触发,或在一个或多个指定表的列发生更新时触发。
-
SQLite 只支持 FOR EACH ROW 触发器(Trigger),没有 FOR EACH STATEMENT 触发器(Trigger)。因此,明确指定 FOR EACH ROW 是可选的。
-
WHEN 子句和触发器(Trigger)动作可能访问 使用表单NEW.column-name和OLD.column-name的引用插入、删除或更新的 行元素,其中 column-name 是从与触发器关联的表的列的名称。
-
如果提供 WHEN 子句,则只针对 WHEN 子句为真的指定行执行 SQL 语句。如果没有提供 WHEN 子句,则针对所有行执行 SQL 语句。
-
BEFORE 或 AFTER 关键字决定何时执行触发器动作,决定是在关联行的插入、修改或删除之前或者之后执行触发器动作。
-
当触发器相关联的表删除时,自动删除触发器(Trigger)。
-
要修改的表必须存在于同一数据库中,作为触发器被附加的表或视图,且必须只使用 tablename,而不是 database.tablename。
-
一个特殊的 SQL 函数 RAISE() 可用于触发器程序内抛出异常。
CREATE TRIGGER trigger_name [BEFORE|AFTER] event_name --event_name 可以是在所提到的表 table_name 上的 INSERT、DELETE 和 UPDATE 数据库操作,可以在表名后选择指定 FOR EACH ROW
ON table_name
BEGIN
-- 触发器逻辑 --
END;
--以下为示例
sqlite> CREATE TABLE COMPANY(
ID INT PRIMARY KEY NOT NULL,
NAME TEXT NOT NULL,
AGE INT NOT NULL,
ADDRESS CHAR(50),
SALARY REAL
);
sqlite> CREATE TABLE AUDIT(
EMP_ID INT NOT NULL,
ENTRY_DATE TEXT NOT NULL
);
sqlite> CREATE TRIGGER audit_log AFTER INSERT
ON COMPANY
BEGIN
INSERT INTO AUDIT(EMP_ID, ENTRY_DATE) VALUES (new.ID, datetime('now'));
END;
列出触发器(TRIGGERS)
sqlite> SELECT name FROM sqlite_master
WHERE type = 'trigger';
删除触发器(TRIGGERS)
sqlite> DROP TRIGGER trigger_name;
SQLite 索引(Index)
索引(Index)是一种特殊的查找表,数据库搜索引擎用来加快数据检索。简单地说,索引是一个指向表中数据的指针。
索引有助于加快 SELECT 查询和 WHERE 子句,但它会减慢使用 UPDATE 和 INSERT 语句时的数据输入。索引可以创建或删除,但不会影响数据。
使用 CREATE INDEX 语句创建索引,它允许命名索引,指定表及要索引的一列或多列,并指示索引是升序排列还是降序排列。
索引也可以是唯一的,与 UNIQUE 约束类似,在列上或列组合上防止重复条目。
CREATE INDEX index_name ON table_name;
CREATE INDEX index_name --单列索引
ON table_name (column_name);
CREATE UNIQUE INDEX index_name --唯一索引
on table_name (column_name);
CREATE INDEX index_name
on table_name (column1, column2); --组合索引
/*
是否要创建一个单列索引还是组合索引,要考虑到您在作为查询过滤条件的 WHERE 子句中使用非常频繁的列。
如果值使用到一个列,则选择使用单列索引。如果在作为过滤的 WHERE 子句中有两个或多个列经常使用,则选择使用组合索引。
*/
列出数据库索引
sqlite> SELECT * FROM sqlite_master WHERE type = 'index';
删除数据库索引
DROP INDEX index_name; --注意,当删除索引时,性能可能会下降可能会提高
什么情况下要避免使用索引?
虽然索引的目的在于提高数据库的性能,但这里有几个情况需要避免使用索引。使用索引时,应重新考虑下列准则:
- 索引不应该使用在较小的表上。
- 索引不应该使用在有频繁的大批量的更新或插入操作的表上。
- 索引不应该使用在含有大量的 NULL 值的列上。
- 索引不应该使用在频繁操作的列上。
SQLite Indexed By
“INDEXED BY index-name” 子句规定必须需要命名的索引来查找前面表中值。
如果索引名 index-name 不存在或不能用于查询,然后 SQLite 语句的准备失败。
“NOT INDEXED” 子句规定当访问前面的表(包括由 UNIQUE 和 PRIMARY KEY 约束创建的隐式索引)时,没有使用索引。
然而,即使指定了 “NOT INDEXED”,INTEGER PRIMARY KEY 仍然可以被用于查找条目。
SELECT|DELETE|UPDATE column1, column2...
INDEXED BY (index_name)
table_name
WHERE (CONDITION);
SQLite Alter
QLite 的 ALTER TABLE 命令不通过执行一个完整的转储和数据的重载来修改已有的表。您可以使用 ALTER TABLE 语句重命名表,使用 ALTER TABLE 语句还可以在已有的表中添加额外的列。
在 SQLite 中,除了重命名表和在已有的表中添加列,ALTER TABLE 命令不支持其他操作。
ALTER TABLE database_name.table_name RENAME TO new_table_name;
ALTER TABLE database_name.table_name ADD COLUMN column_def...;
SQLite Truncate Table
在 SQLite 中,并没有 TRUNCATE TABLE 命令,但可以使用 SQLite 的 DELETE 命令从已有的表中删除全部的数据。
sqlite> DELETE FROM table_name; --这种方法无法将递增数归零。
如果要将递增数归零,可以使用以下方法:
sqlite> DELETE FROM sqlite_sequence WHERE name = 'table_name';
/*
当 SQLite 数据库中包含自增列时,会自动建立一个名为 sqlite_sequence 的表。这个表包含两个列:name 和 seq。name 记录自增列所在的表,seq 记录当前序号(下一条记录的编号就是当前序号加 1)。如果想把某个自增列的序号归零,只需要修改 sqlite_sequence 表就可以了。
*/
UPDATE sqlite_sequence SET seq = 0 WHERE name = 'table_name';
SQLite 视图(View)
视图(View)只不过是通过相关的名称存储在数据库中的一个 SQLite 语句。
视图(View)实际上是一个以预定义的 SQLite 查询形式存在的表的组合。
视图(View)可以包含一个表的所有行或从一个或多个表选定行。可以从一个或多个表创建,这取决于要创建视图的 SQLite 查询。
视图(View)是一种虚表,允许用户实现以下几点:
- 用户或用户组查找结构数据的方式更自然或直观。
- 限制数据访问,用户只能看到有限的数据,而不是完整的表。
- 汇总各种表中的数据,用于生成报告。
- SQLite 视图是只读的,因此可能无法在视图上执行 DELETE、INSERT 或 UPDATE 语句。但是可以在视图上创建一个触发器,当尝试 DELETE、INSERT 或 UPDATE 视图时触发,需要做的动作在触发器内容中定义。
创建视图
CREATE [TEMP | TEMPORARY] VIEW view_name AS --如果使用了可选的 TEMP 或 TEMPORARY 关键字,则将在临时数据库中创建视图。
SELECT column1, column2.....
FROM table_name
WHERE [condition];
删除视图
sqlite> DROP VIEW view_name;
SQLite 事务(Transaction)
事务(Transaction)是一个对数据库执行工作单元。事务(Transaction)是以逻辑顺序完成的工作单位或序列,可以是由用户手动操作完成,也可以是由某种数据库程序自动完成。
事务(Transaction)是指一个或多个更改数据库的扩展。例如,如果您正在创建一个记录或者更新一个记录或者从表中删除一个记录,那么您正在该表上执行事务。重要的是要控制事务以确保数据的完整性和处理数据库错误。
实际上,您可以把许多的 SQLite 查询联合成一组,把所有这些放在一起作为事务的一部分进行执行。
事务(Transaction)具有以下四个标准属性,通常根据首字母缩写为 ACID:
原子性(Atomicity):确保工作单位内的所有操作都成功完成,否则,事务会在出现故障时终止,之前的操作也会回滚到以前的状态。
一致性(Consistency) :确保数据库在成功提交的事务上正确地改变状态。
隔离性(Isolation):使事务操作相互独立和透明。
持久性(Durability):确保已提交事务的结果或效果在系统发生故障的情况下仍然存在。
事务控制需要结合DML 命令 INSERT、UPDATE 和 DELETE 一起使用,事务控制命令有:
BEGIN:开始事务处理,或者使用BEGIN TRANSACTION命令。
COMMIT:保存更改,或者可以使用 END TRANSACTION 命令。
ROLLBACK:回滚所做的更改,只能用于撤销自上次发出 COMMIT 或 ROLLBACK 命令以来的事务。
sqlite> BEGIN;
sqlite> DELETE FROM COMPANY WHERE AGE = 25;
sqlite> ROLLBACK;
SQLite 子查询
子查询或称为内部查询、嵌套查询,指的是在 SQLite 查询中的 WHERE 子句中嵌入查询语句。
子查询可以与 SELECT、INSERT、UPDATE 和 DELETE 语句一起使用,可伴随着使用运算符如 =、<、>、>=、<=、IN、BETWEEN 等。
以下是子查询必须遵循的几个规则:
- 子查询必须用括号括起来。
- 子查询在 SELECT 子句中只能有一个列,除非在主查询中有多列,与子查询的所选列进行比较。
- ORDER BY 不能用在子查询中,虽然主查询可以使用 ORDER BY。可以在子查询中使用 GROUP BY,功能与 ORDER BY 相同。
- 子查询返回多于一行,只能与多值运算符一起使用,如 IN 运算符。
- BETWEEN 运算符不能与子查询一起使用,但是 BETWEEN 可在子查询内使用。
SELECT 语句中的子查询使用
SELECT * FROM COMPANY WHERE ID IN
(SELECT ID FROM COMPANY WHERE SALARY > 45000) ;
INSERT 语句中的子查询使用
INSERT INTO COMPANY_BKP SELECT * FROM COMPANY WHERE ID IN
(SELECT ID FROM COMPANY) ;
UPDATE 语句中的子查询使用
UPDATE COMPANY SET SALARY = SALARY * 0.50 WHERE AGE IN
(SELECT AGE FROM COMPANY_BKP WHERE AGE >= 27 );
DELETE 语句中的子查询使用
DELETE FROM COMPANY WHERE AGE IN
(SELECT AGE FROM COMPANY_BKP WHERE AGE > 27 );
SQLite Autoincrement(自动递增)
SQLite 的 AUTOINCREMENT 是一个关键字,用于表中的字段值自动递增。我们可以在创建表时在特定的列名称上使用 AUTOINCREMENT 关键字实现该字段值的自动增加。
关键字 AUTOINCREMENT 只能用于整型(INTEGER)字段。
SQLite Vacuum
VACUUM 命令通过复制主数据库中的内容到一个临时数据库文件,然后清空主数据库,并从副本中重新载入原始的数据库文件。这消除了空闲页,把表中的数据排列为连续的,另外会清理数据库文件结构。
如果表中没有明确的整型主键(INTEGER PRIMARY KEY),VACUUM 命令可能会改变表中条目的行 ID(ROWID)。VACUUM 命令只适用于主数据库,附加的数据库文件是不可能使用 VACUUM 命令。
如果有一个活动的事务,VACUUM 命令就会失败。VACUUM 命令是一个用于内存数据库的任何操作。由于 VACUUM 命令从头开始重新创建数据库文件,所以 VACUUM 也可以用于修改许多数据库特定的配置参数。
下面是在命令提示符中对整个数据库发出 VACUUM 命令的语法:
$sqlite3 database_name "VACUUM;"
您也可以在 SQLite 提示符中运行 VACUUM,如下所示:
sqlite> VACUUM;
您也可以在特定的表上运行 VACUUM,如下所示:
sqlite> VACUUM table_name;
SQLite 的 Auto-VACUUM 与 VACUUM 不大一样,它只是把空闲页移到数据库末尾,从而减小数据库大小。通过这样做,它可以明显地把数据库碎片化,而 VACUUM 则是反碎片化。所以 Auto-VACUUM 只会让数据库更小。
在 SQLite 提示符中,您可以通过下面的编译运行,启用/禁用 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
您可以从命令提示符中运行下面的命令来检查 auto-vacuum 设置:
$sqlite3 database_name "PRAGMA auto_vacuum;"
SQLite 日期 & 时间
现在让我们使用 SQLite 提示符尝试不同的实例。
下面是计算当前日期:
sqlite> SELECT date('now'); --2013-05-07
下面是计算当前月份的最后一天:
sqlite> SELECT date('now','start of month','+1 month','-1 day'); --2013-05-31
下面是计算给定 UNIX 时间戳 1092941466 的日期和时间:
sqlite> SELECT datetime(1092941466, 'unixepoch'); --2004-08-19 18:51:06
下面是计算给定 UNIX 时间戳 1092941466 相对本地时区的日期和时间:
sqlite> SELECT datetime(1092941466, 'unixepoch', 'localtime'); --2004-08-19 11:51:06
下面是计算当前的 UNIX 时间戳:
sqlite> SELECT strftime('%s','now'); --1367926057
下面是计算从 2004 年某一特定时刻以来的秒数:
sqlite> SELECT strftime('%s','now') - strftime('%s','2004-01-01 02:34:56'); 295001572
下面是计算当年 10 月的第一个星期二的日期:
sqlite> SELECT date('now','start of year','+9 months','weekday 2'); 2013-10-01
在 UTC 与本地时间值之间进行转换,当格式化日期时,使用 utc 或 localtime 修饰符,如下所示:
sqlite> SELECT time('12:00', 'localtime'); --05:00:00
sqlite> SELECT time('12:00', 'utc'); --19:00:00
SQLite 常用函数
SQLite 有许多内置函数用于处理字符串或数字数据。
- SQLite COUNT 函数
SQLite COUNT 聚集函数是用来计算一个数据库表中的行数。 - SQLite MAX 函数
SQLite MAX 聚合函数允许我们选择某列的最大值。 - SQLite MIN 函数
SQLite MIN 聚合函数允许我们选择某列的最小值。
4.SQLite AVG 函数
SQLite AVG 聚合函数计算某列的平均值。 - SQLite SUM 函数
SQLite SUM 聚合函数允许为一个数值列计算总和。 - SQLite RANDOM 函数
SQLite RANDOM 函数返回一个介于 -9223372036854775808 和 +9223372036854775807 之间的伪随机整数。 - SQLite ABS 函数
SQLite ABS 函数返回数值参数的绝对值。 - SQLite UPPER 函数
SQLite UPPER 函数把字符串转换为大写字母。 - SQLite LOWER 函数
SQLite LOWER 函数把字符串转换为小写字母。 - SQLite LENGTH 函数
SQLite LENGTH 函数返回字符串的长度。 - SQLite sqlite_version 函数
SQLite sqlite_version 函数返回 SQLite 库的版本。