SQLite实践

SQLite 简介

SQLite是一个软件库,实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。SQLite是一个增长最快的数据库引擎,这是在普及方面的增长,与它的尺寸大小无关。SQLite 源代码不受版权限制。

什么是 SQLite?

SQLite是一个进程内的库,实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。它是一个零配置的数据库,这意味着与其他数据库一样,您不需要在系统中配置。
就像其他数据库,SQLite 引擎不是一个独立的进程,可以按应用程序需求进行静态或动态连接。SQLite 直接访问其存储文件

为什么要用 SQLite?

SQLite 局限性

特性 描述
RIGHT OUTER JOIN 只实现了 LEFT OUTER JOIN。
FULL OUTER JOIN 只实现了 LEFT OUTER JOIN。
ALTER TABLE 支持 RENAME TABLE 和 ALTER TABLE 的 ADD COLUMN variants 命令,不支持 DROP COLUMN、ALTER COLUMN、ADD CONSTRAINT。
Trigger 支持 支持 FOR EACH ROW 触发器,但不支持 FOR EACH STATEMENT 触发器。
VIEWs 在 SQLite 中,视图是只读的。您不可以在视图上执行 DELETE、INSERT 或 UPDATE 语句。
GRANT 和 REVOKE 可以应用的唯一的访问权限是底层操作系统的正常文件访问权限。

SQLite 命令

与关系数据库进行交互的标准 SQLite 命令类似于 SQL。命令包括 CREATE、SELECT、INSERT、UPDATE、DELETE 和 DROP。这些命令基于它们的操作性质可分为以下几种:

1、DDL - 数据定义语言

命令 描述
CREATE 创建一个新的表,一个表的视图,或者数据库中的其他对象。
ALTER 修改数据库中的某个已有的数据库对象,比如一个表。
DROP 删除整个表,或者表的视图,或者数据库中的其他对象。

2、DML - 数据操作语言

命令 描述
INSERT 创建一条记录。
UPDATE 修改记录。
DELETE 删除记录。

3、DQL - 数据查询语言

命令 描述
SELECT 从一个或多个表中检索某些记录。

一、安装

yum install -y sqlite

二、常用指令

1、查看已经进入sqlite的方式

sqlite3
[root@localhost ~]# sqlite3
SQLite version 3.7.17 2013-05-20 00:56:22
Enter ".help" for instructions <---输入.help查看说明
Enter SQL statements terminated with a ";" <---sql语句以分号结尾

2、点指令

因为以.开头,所以叫点指令,不需要分号;
sqlite> 提示符与点命令之间没有空格,否则将无法正常工作。

.help

sqlite> .help
.backup ?DB? FILE Backup DB (default "main") to FILE
.bail ON|OFF Stop after hitting an error. Default OFF
.databases List names and files of attached databases
.dump ?TABLE? ... Dump the database in an SQL text format
If TABLE specified, only dump tables matching
LIKE pattern TABLE.
.echo ON|OFF Turn command echo on or off
.exit Exit this program
.explain ?ON|OFF? Turn output mode suitable for EXPLAIN on or off.
With no args, it turns EXPLAIN on.
.header(s) ON|OFF Turn display of headers on or off
.help Show this message
.import FILE TABLE Import data from FILE into TABLE
.indices ?TABLE? Show names of all indices
If TABLE specified, only show indices for tables
matching LIKE pattern TABLE.
.load FILE ?ENTRY? Load an extension library
.log FILE|off Turn logging on or off. FILE can be stderr/stdout
.mode MODE ?TABLE? Set output mode where MODE is one of:
csv Comma-separated values
column Left-aligned columns. (See .width)
html HTML <table> code
insert SQL insert statements for TABLE
line One value per line
list Values delimited by .separator string
tabs Tab-separated values
tcl TCL list elements
.nullvalue STRING Use STRING in place of NULL values
.output FILENAME Send output to FILENAME
.output stdout Send output to the screen
.print STRING... Print literal STRING
.prompt MAIN CONTINUE Replace the standard prompts
.quit Exit this program
.read FILENAME Execute SQL in FILENAME
.restore ?DB? FILE Restore content of DB (default "main") from FILE
.schema ?TABLE? Show the CREATE statements
If TABLE specified, only show tables matching
LIKE pattern TABLE.
.separator STRING Change separator used by output mode and .import
.show Show the current values for various settings
.stats ON|OFF Turn stats on or off
.tables ?TABLE? List names of tables
If TABLE specified, only list tables matching
LIKE pattern TABLE.
.timeout MS Try opening locked tables for MS milliseconds
.trace FILE|off Output each SQL statement as it is run
.vfsname ?AUX? Print the name of the VFS stack
.width NUM1 NUM2 ... Set column widths for "column" mode
.timer ON|OFF Turn the CPU timer measurement on or off

以上是关于点指令的说明

命令 描述
.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 on、off 开启或关闭日志。FILE 文件可以是 stderr(标准错误)/stdout(标准输出)。
.mode MODE 设置输出模式,MODE 可以是下列之一:csv 逗号分隔的值 ;column 左对齐的列html HTML 的 代码;insert TABLE 表的 SQL 插入(insert)语句;line 每行一个值;list 由 .separator 字符串分隔的值;tabs 由 Tab 分隔的值;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> .databases
seq name file
--- --------------- ----------------------------------------------------------
0 main
MariaDB [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| wiki |
+--------------------+
4 rows in set (0.00 sec)
sqlite> .show
echo: off
explain: off
headers: off
mode: list
nullvalue: ""
output: stdout
separator: "|"
stats: off
width:

语句

常用语句示例

ANALYZE;
or
ANALYZE database_name;
or
ANALYZE database_name.table_name;
SELECT column1, column2....columnN
FROM table_name
WHERE CONDITION-1 {AND|OR} CONDITION-2;
ALTER TABLE table_name ADD COLUMN column_def...;
ALTER TABLE table_name RENAME TO new_table_name;
ATTACH DATABASE 'DatabaseName' As 'Alias-Name';
BEGIN;
or
BEGIN EXCLUSIVE TRANSACTION;
SELECT column1, column2....columnN
FROM table_name
WHERE column_name BETWEEN val-1 AND val-2;
COMMIT;
CREATE INDEX index_name
ON table_name ( column_name COLLATE NOCASE );
CREATE UNIQUE INDEX index_name
ON table_name ( column1, column2,...columnN);
CREATE TABLE table_name(
column1 datatype,
column2 datatype,
column3 datatype,
.....
columnN datatype,
PRIMARY KEY( one or more columns )
);
CREATE TRIGGER database_name.trigger_name
BEFORE INSERT ON table_name FOR EACH ROW
BEGIN
stmt1;
stmt2;
....
END;
CREATE VIEW database_name.view_name AS
SELECT statement....;
CREATE VIRTUAL TABLE database_name.table_name USING weblog( access.log );
or
CREATE VIRTUAL TABLE database_name.table_name USING fts3( );
COMMIT;
SELECT COUNT(column_name)
FROM table_name
WHERE CONDITION;

-SQLite DROP TABLE 语句:

DROP TABLE database_name.table_name;
DROP VIEW view_name;
DROP TRIGGER trigger_name
SELECT column1, column2....columnN
FROM table_name
WHERE column_name EXISTS (SELECT * FROM table_name );
EXPLAIN INSERT statement...;
or
EXPLAIN QUERY PLAN SELECT statement...;
SELECT column1, column2....columnN
FROM table_name
WHERE column_name GLOB { PATTERN };
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);
INSERT INTO table_name( column1, column2....columnN)
VALUES ( value1, value2....valueN);
SELECT column1, column2....columnN
FROM table_name
WHERE column_name IN (val-1, val-2,...val-N);
SELECT column1, column2....columnN
FROM table_name
WHERE column_name LIKE { PATTERN };
SELECT column1, column2....columnN
FROM table_name
WHERE column_name NOT IN (val-1, val-2,...val-N);
SELECT column1, column2....columnN
FROM table_name
WHERE CONDITION
ORDER BY column_name {ASC|DESC};
PRAGMA pragma_name;
PRAGMA page_size;
PRAGMA cache_size = 1024;
PRAGMA table_info(table_name);
RELEASE savepoint_name;
REINDEX collation_name;
REINDEX database_name.index_name;
REINDEX database_name.table_name;
ROLLBACK;
or
ROLLBACK TO SAVEPOINT savepoint_name;
SAVEPOINT savepoint_name;
SELECT column1, column2....columnN
FROM table_name;
UPDATE table_name
SET column1 = value1, column2 = value2....columnN=valueN
[ WHERE CONDITION ];
VACUUM;
SELECT column1, column2....columnN
FROM table_name
WHERE CONDITION;

三、常用操作

1、创建数据库

sqlite3 DatabaseName.db
[root@localhost lcr]# sqlite3 test.db
SQLite version 3.7.17 2013-05-20 00:56:22
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> .databases
seq name file
--- --------------- ----------------------------------------------------------
0 main /home/lcr/test.db

2、导出/导出数据库

导出

DatabaseName.db .dump > filename
[root@localhost lcr]# sqlite3 test.db .dump > test.sql
[root@localhost lcr]# ls
7A0V+6bZ.bin perl5 test.sql 模板 图片 下载 桌面
b7ZpN4fk.bin test.db 公共 视频 文档 音乐

导入

3、附加/分离数据库

附加

ATTACH DATABASE 'DatabaseName' As 'Alias-Name';
sqlite> ATTACH DATABASE 'test.db' AS 'TEST';
sqlite> .databases
seq name file
--- --------------- ----------------------------------------------------------
0 main /home/lcr/test.db
2 TEST /home/lcr/test.db

其中ATTACH DATABASE,AS注意大小写
数据库名main,temp是保留的名字,不能使用

分离

DETACH DATABASE 'Alias-Name';
sqlite> .databases
seq name file
--- --------------- ----------------------------------------------------------
0 main /home/lcr/test.db
2 TEST /home/lcr/test.db
sqlite> DETACH DATABASE 'TEST';
sqlite> .databases
seq name file
--- --------------- ----------------------------------------------------------
0 main /home/lcr/test.db

4、创建/删除表

创建表

CREATE TABLE database_name.table_name(
column1 datatype PRIMARY KEY(one or more columns),
column2 datatype,
column3 datatype,
.....
columnN datatype,
);
sqlite> CREATE TABLE TEST.list(
...> ID INT PRIMARY KEY NOT NULL,
...> ADDRESS CHAR(50)
...> );
sqlite> .schema list
CREATE TABLE list(
ID INT PRIMARY KEY NOT NULL,
ADDRESS CHAR(50)
);

删除表

DROP TABLE database_name.table_name;
sqlite> .tables
TEST.list list
sqlite> DROP TABLE list;
sqlite> .tables

Insert 语句

SQLite 的 INSERT INTO 语句用于向数据库的某个表中添加新的数据行。

INSERT INTO 语句有两种基本语法,

INSERT INTO TABLE_NAME [(column1, column2, column3,...columnN)]
VALUES (value1, value2, value3,...valueN);

在这里,column1, column2,…columnN 是要插入数据的表中的列的名称。
如果要为表中的所有列添加值,您也可以不需要在 SQLite 查询中指定列名称。但要确保值的顺序与列在表中的顺序一致。

SQLite 的 INSERT INTO 语法如下:

INSERT INTO TABLE_NAME VALUES (value1,value2,value3,...valueN);

实例
假设您已经在 testDB.db 中创建了 COMPANY表,如下所示:

sqlite> CREATE TABLE COMPANY(
ID INT PRIMARY KEY NOT NULL,
NAME TEXT NOT NULL,
AGE INT NOT NULL,
ADDRESS CHAR(50),
SALARY REAL
);

现在,下面的语句将在 COMPANY 表中创建六个记录:

INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)
VALUES (1, 'Paul', 32, 'California', 20000.00 );
INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)
VALUES (2, 'Allen', 25, 'Texas', 15000.00 );
INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)
VALUES (3, 'Teddy', 23, 'Norway', 20000.00 );
INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)
VALUES (4, 'Mark', 25, 'Rich-Mond ', 65000.00 );
INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)
VALUES (5, 'David', 27, 'Texas', 85000.00 );
INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)
VALUES (6, 'Kim', 22, 'South-Hall', 45000.00 );

您也可以使用第二种语法在 COMPANY 表中创建一个记录,如下所示:

INSERT INTO COMPANY VALUES (7, 'James', 24, 'Houston', 10000.00 );

上面的所有语句将在 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

使用一个表来填充另一个表
您可以通过在一个有一组字段的表上使用 select 语句,填充数据到另一个表中。下面是语法:

INSERT INTO first_table_name [(column1, column2, ... columnN)]
SELECT column1, column2, ...columnN
FROM second_table_name
[WHERE condition];

Update 语句

SQLite 的 UPDATE 查询用于修改表中已有的记录。可以使用带有 WHERE 子句的 UPDATE 查询来更新选定行,否则所有的行都会被更新。

UPDATE table_name
SET column1 = value1, column2 = value2...., columnN = valueN
WHERE [condition];

可以使用 AND 或 OR 运算符来结合 N 个数量的条件。

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

下面是一个实例,它会更新 ID 为 6 的客户地址:

sqlite> UPDATE COMPANY SET ADDRESS = 'Texas' WHERE ID = 6;

现在,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 Texas 45000.0
7 James 24 Houston 10000.0

如果您想修改 COMPANY 表中 ADDRESS 和 SALARY 列的所有值,则不需要使用 WHERE 子句,UPDATE 查询如下:

sqlite> UPDATE COMPANY SET ADDRESS = 'Texas', SALARY = 20000.00;

现在,COMPANY 表有以下记录:

ID NAME AGE ADDRESS SALARY
---------- ---------- ---------- ---------- ----------
1 Paul 32 Texas 20000.0
2 Allen 25 Texas 20000.0
3 Teddy 23 Texas 20000.0
4 Mark 25 Texas 20000.0
5 David 27 Texas 20000.0
6 Kim 22 Texas 20000.0
7 James 24 Texas 20000.0

Delete 语句

SQLite 的 DELETE 查询用于删除表中已有的记录。可以使用带有 WHERE 子句的 DELETE 查询来删除选定行,否则所有的记录都会被删除。

DELETE FROM table_name
WHERE [condition];

可以使用 AND 或 OR 运算符来结合 N 个数量的条件。

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

下面是一个实例,它会删除 ID 为 7 的客户:

sqlite> DELETE FROM COMPANY WHERE ID = 7;

现在,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

如果您想要从 COMPANY 表中删除所有记录,则不需要使用 WHERE 子句,DELETE 查询如下:

sqlite> DELETE FROM COMPANY;

现在,COMPANY 表中没有任何的记录,因为所有的记录已经通过 DELETE 语句删除。

Select 语句

SQLite 的 SELECT 语句用于从 SQLite 数据库表中获取数据,以结果表的形式返回数据。这些结果表也被称为结果集。
语法

SELECT column1, column2, columnN FROM table_name;

在这里,column1, column2…是表的字段,他们的值即是您要获取的。如果您想获取所有可用的字段,那么可以使用下面的语法:

SELECT * FROM table_name;

假设 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

下面是一个实例,使用 SELECT 语句获取并显示所有这些记录。在这里,前三个命令被用来设置正确格式化的输出。

sqlite>.header on
sqlite>.mode column
sqlite> SELECT * FROM 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

如果只想获取 COMPANY 表中指定的字段,则使用下面的查询:

sqlite> SELECT ID, NAME, SALARY FROM COMPANY;

上面的查询会产生以下结果:

ID NAME SALARY
---------- ---------- ----------
1 Paul 20000.0
2 Allen 15000.0
3 Teddy 20000.0
4 Mark 65000.0
5 David 85000.0
6 Kim 45000.0
7 James 10000.0

有时,由于要显示的列的默认宽度导致 .mode column,这种情况下,输出被截断。此时,您可以使用 .width num, num…. 命令设置显示列的宽度,如下所示:

sqlite>.width 10, 20, 10
sqlite>SELECT * FROM COMPANY;

上面的 .width 命令设置第一列的宽度为 10,第二列的宽度为 20,第三列的宽度为 10。因此上述 SELECT 语句将得到以下结果:

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

Schema 信息
因为所有的点命令只在 SQLite 提示符中可用,所以当您进行带有 SQLite 的编程时,您要使用下面的带有 sqlite_master 表的 SELECT 语句来列出所有在数据库中创建的表:

sqlite> SELECT tbl_name FROM sqlite_master WHERE type = 'table';

假设在 testDB.db 中已经存在唯一的 COMPANY 表,则将产生以下结果:

tbl_name
----------
COMPANY

您可以列出关于 COMPANY 表的完整信息,如下所示:

sqlite> SELECT sql FROM sqlite_master WHERE type = 'table' AND tbl_name = 'COMPANY';

假设在 testDB.db 中已经存在唯一的 COMPANY 表,则将产生以下结果:

CREATE TABLE COMPANY(
ID INT PRIMARY KEY NOT NULL,
NAME TEXT NOT NULL,
AGE INT NOT NULL,
ADDRESS CHAR(50),
SALARY REAL
)

总结

2017年9月22日23:44:27
到目前为止,没有遇到账户,权限等问题
以mediawiki为例,创建数据库时

Alt text

仅仅设置目录,数据库名称

Alt text
此处涉及的是权限问题
并给出了解决方案

cd /var/www
mkdir data
chgrp apache data
chmod g+w data
[root@localhost data]# ll
总用量 2772
drwxr-xr-x 2 apache apache 6 9月 22 23:57 locks
-rw-r--r-- 1 apache apache 2823168 9月 23 00:02 my_wiki.sqlite
-rw-r--r-- 1 apache apache 9216 9月 23 00:02 wikicache.sqlite

MediaWiki支持以下数据库系统:

MySQL是MediaWiki的首选数据库,对它的支持最为完备。MediaWiki也可以在MariaDB和Percona Server下工作,它们与MySQL兼容。(如何将对MySQL的支持编译进PHP中)
PostgreSQL是一种流行的开源数据库系统,可作为MySQL的替代(如何将对PostgreSQL的支持编译进PHP中)
Oracle是一种商用企业级的数据库。(如何将对OCI8的支持编译进PHP中)
Microsoft SQL Server是一个适用于Windows的商业性企业数据库。(如何编译带有SQLSRV支持的PHP)
SQLite是一种轻量级的数据库系统,能被良好地支持。(如何将对SQLite的支持编译进PHP中,须使用PDO)

如果您在下面列出的数据库系统中没有找到您希望使用的系统,请根据上方链向的指引启用支持。