最轻巧的数据SQLite高级教程 DAy04

1、SQLite Joins

SQLite 的 Joins 子句用于结合两个或多个数据库中表的记录。JOIN 是一种通过共同值来结合两个表中字段的手段。

SQL 定义了三种主要类型的连接:

  • 交叉连接 - CROSS JOIN

  • 内连接 - INNER JOIN

  • 外连接 - OUTER JOIN

交叉连接 - CROSS JOIN

交叉连接(CROSS JOIN)把第一个表的每一行与第二个表的每一行进行匹配。如果两个输入表分别有 x 和 y 行,则结果表有 x*y 行。由于交叉连接(CROSS JOIN)有可能产生非常大的表,使用时必须谨慎,只在适当的时候使用它们。

下面是交叉连接(CROSS JOIN)的语法:

SELECT ... FROM table1 CROSS JOIN table2 ...

在我们继续之前,让我们假设有两个表 COMPANY 和 DEPARTMENT。我们已经看到了用来填充 COMPANY 表的 INSERT 语句。现在让我们假设 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

最后,我们在 DEPARTMENT 表中有下列的记录列表:

ID          DEPT        EMP_ID
----------  ----------  ----------
1           IT Billing  1
2           Engineerin  2
3           Finance     7

基于上面的表,我们可以写一个交叉连接(CROSS JOIN),如下所示:

sqlite> SELECT EMP_ID, NAME, DEPT FROM COMPANY CROSS JOIN DEPARTMENT;

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

EMP_ID      NAME        DEPT
----------  ----------  ----------
1           Paul        IT Billing
2           Paul        Engineerin
7           Paul        Finance
1           Allen       IT Billing
2           Allen       Engineerin
7           Allen       Finance
1           Teddy       IT Billing
2           Teddy       Engineerin
7           Teddy       Finance
1           Mark        IT Billing
2           Mark        Engineerin
7           Mark        Finance
1           David       IT Billing
2           David       Engineerin
7           David       Finance
1           Kim         IT Billing
2           Kim         Engineerin
7           Kim         Finance
1           James       IT Billing
2           James       Engineerin
7           James       Finance

内连接 - INNER JOIN

内连接(INNER JOIN)根据连接谓词结合两个表(table1 和 table2)的列值来创建一个新的结果表。查询会把 table1 中的每一行与 table2 中的每一行进行比较,找到所有满足连接谓词的行的匹配对。当满足连接谓词时,A 和 B 行的每个匹配对的列值会合并成一个结果行。

内连接(INNER JOIN)是最常见的连接类型,是默认的连接类型。INNER 关键字是可选的。

下面是内连接(INNER JOIN)的语法:

SELECT ... FROM table1 [INNER] JOIN table2 ON conditional_expression ...

为了避免冗余,并保持较短的措辞,可以使用 USING 表达式声明内连接(INNER JOIN)条件。这个表达式指定一个或多个列的列表:

SELECT ... FROM table1 JOIN table2 USING ( column1 ,... ) ...

自然连接(NATURAL JOIN)类似于 JOIN...USING,只是它会自动测试存在两个表中的每一列的值之间相等值:

SELECT ... FROM table1 NATURAL JOIN table2...

基于上面的表,我们可以写一个内连接(INNER JOIN),如下所示:

sqlite> SELECT EMP_ID, NAME, DEPT FROM COMPANY INNER JOIN DEPARTMENT
        ON COMPANY.ID = DEPARTMENT.EMP_ID;

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

EMP_ID      NAME        DEPT
----------  ----------  ----------
1           Paul        IT Billing
2           Allen       Engineerin
7           James       Finance

外连接 - OUTER JOIN

外连接(OUTER JOIN)是内连接(INNER JOIN)的扩展。虽然 SQL 标准定义了三种类型的外连接:LEFT、RIGHT、FULL,但 SQLite 只支持 左外连接(LEFT OUTER JOIN)

外连接(OUTER JOIN)声明条件的方法与内连接(INNER JOIN)是相同的,使用 ON、USING 或 NATURAL 关键字来表达。最初的结果表以相同的方式进行计算。一旦主连接计算完成,外连接(OUTER JOIN)将从一个或两个表中任何未连接的行合并进来,外连接的列使用 NULL 值,将它们附加到结果表中。

下面是左外连接(LEFT OUTER JOIN)的语法:

SELECT ... FROM table1 LEFT OUTER JOIN table2 ON conditional_expression ...

为了避免冗余,并保持较短的措辞,可以使用 USING 表达式声明外连接(OUTER JOIN)条件。这个表达式指定一个或多个列的列表:

SELECT ... FROM table1 LEFT OUTER JOIN table2 USING ( column1 ,... ) ...

基于上面的表,我们可以写一个外连接(OUTER JOIN),如下所示:

sqlite> SELECT EMP_ID, NAME, DEPT FROM COMPANY LEFT OUTER JOIN DEPARTMENT
        ON COMPANY.ID = DEPARTMENT.EMP_ID;

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

EMP_ID      NAME        DEPT
----------  ----------  ----------
1           Paul        IT Billing
2           Allen       Engineerin
            Teddy
            Mark
            David
            Kim
7           James       Finance

2、SQLite Unions 子句

SQLite的 UNION 子句/运算符用于合并两个或多个 SELECT 语句的结果,不返回任何重复的行。

为了使用 UNION,每个 SELECT 被选择的列数必须是相同的,相同数目的列表达式,相同的数据类型,并确保它们有相同的顺序,但它们不必具有相同的长度。

语法

UNION 的基本语法如下:

SELECT column1 [, column2 ]
FROM table1 [, table2 ]
[WHERE condition]

UNION

SELECT column1 [, column2 ]
FROM table1 [, table2 ]
[WHERE condition]

这里给定的条件根据需要可以是任何表达式。

实例

假设有下面两个表,(1)COMPANY 表如下所示:

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

(2)另一个表是 DEPARTMENT,如下所示:

ID          DEPT                  EMP_ID
----------  --------------------  ----------
1           IT Billing            1
2           Engineering           2
3           Finance               7
4           Engineering           3
5           Finance               4
6           Engineering           5
7           Finance               6

现在,让我们使用 SELECT 语句及 UNION 子句来连接两个表,如下所示:

sqlite> SELECT EMP_ID, NAME, DEPT FROM COMPANY INNER JOIN DEPARTMENT
        ON COMPANY.ID = DEPARTMENT.EMP_ID
   UNION
     SELECT EMP_ID, NAME, DEPT FROM COMPANY LEFT OUTER JOIN DEPARTMENT
        ON COMPANY.ID = DEPARTMENT.EMP_ID;

这将产生以下结果:

EMP_ID      NAME                  DEPT
----------  --------------------  ----------
1           Paul                  IT Billing
2           Allen                 Engineerin
3           Teddy                 Engineerin
4           Mark                  Finance
5           David                 Engineerin
6           Kim                   Finance
7           James                 Finance

UNION ALL 子句

UNION ALL 运算符用于结合两个 SELECT 语句的结果,包括重复行。

适用于 UNION 的规则同样适用于 UNION ALL 运算符。

语法

UNION ALL 的基本语法如下:

SELECT column1 [, column2 ]
FROM table1 [, table2 ]
[WHERE condition]

UNION ALL

SELECT column1 [, column2 ]
FROM table1 [, table2 ]
[WHERE condition]

这里给定的条件根据需要可以是任何表达式。

实例

现在,让我们使用 SELECT 语句及 UNION ALL 子句来连接两个表,如下所示:

sqlite> SELECT EMP_ID, NAME, DEPT FROM COMPANY INNER JOIN DEPARTMENT
        ON COMPANY.ID = DEPARTMENT.EMP_ID
   UNION ALL
     SELECT EMP_ID, NAME, DEPT FROM COMPANY LEFT OUTER JOIN DEPARTMENT
        ON COMPANY.ID = DEPARTMENT.EMP_ID;

这将产生以下结果:

最轻巧的数据SQLite高级教程 DAy04

3、SQLite NULL 值

SQLite 的 NULL 是用来表示一个缺失值的项。表中的一个 NULL 值是在字段中显示为空白的一个值。

带有 NULL 值的字段是一个不带有值的字段。NULL 值与零值或包含空格的字段是不同的,理解这点是非常重要的。

语法

创建表时使用 NULL 的基本语法如下:

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

在这里,NOT NULL 表示列总是接受给定数据类型的显式值。这里有两个列我们没有使用 NOT NULL,这意味着这两个列可以为 NULL。

带有 NULL 值的字段在记录创建的时候可以保留为空。

4、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];

假设有下面两个表,(1)COMPANY 表如下所示:

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

(2)另一个表是 DEPARTMENT,如下所示:

ID          DEPT                  EMP_ID
----------  --------------------  ----------
1           IT Billing            1
2           Engineering           2
3           Finance               7
4           Engineering           3
5           Finance               4
6           Engineering           5
7           Finance               6

现在,下面是 表别名 的用法,在这里我们使用 C 和 D 分别作为 COMPANY 和 DEPARTMENT 表的别名:

sqlite> SELECT C.ID, C.NAME, C.AGE, D.DEPT
        FROM COMPANY AS C, DEPARTMENT AS D
        WHERE  C.ID = D.EMP_ID;

上面的 SQLite 语句将产生下面的结果:

ID          NAME        AGE         DEPT
----------  ----------  ----------  ----------
1           Paul        32          IT Billing
2           Allen       25          Engineerin
3           Teddy       23          Engineerin
4           Mark        25          Finance
5           David       27          Engineerin
6           Kim         22          Finance
7           James       24          Finance

让我们看一个 列别名 的实例,在这里 COMPANY_ID 是 ID 列的别名,COMPANY_NAME 是 name 列的别名:

sqlite> SELECT C.ID AS COMPANY_ID, C.NAME AS COMPANY_NAME, C.AGE, D.DEPT
        FROM COMPANY AS C, DEPARTMENT AS D
        WHERE  C.ID = D.EMP_ID;

上面的 SQLite 语句将产生下面的结果:

COMPANY_ID  COMPANY_NAME  AGE         DEPT
----------  ------------  ----------  ----------
1           Paul          32          IT Billing
2           Allen         25          Engineerin
3           Teddy         23          Engineerin
4           Mark          25          Finance
5           David         27          Engineerin
6           Kim           22          Finance
7           James         24          Finance

5、SQLite 触发器(Trigger)

SQLite 的触发器是数据库的回调函数,它会自动执行/指定的数据库事件发生时调用。以下是关于SQLite的触发器的要点: 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() 可用于触发器程序内抛出异常。

语法

创建 触发器(Trigger) 的基本语法如下:

CREATE  TRIGGER trigger_name [BEFORE|AFTER] event_name 
ON table_name
BEGIN
 -- Trigger logic goes here....
END;

在这里,event_name 可以是在所提到的表 table_name 上的 INSERT、DELETE 和 UPDATE 数据库操作。您可以在表名后选择指定 FOR EACH ROW。

以下是在 UPDATE 操作上在表的一个或多个指定列上创建触发器(Trigger)的语法:

CREATE  TRIGGER trigger_name [BEFORE|AFTER] UPDATE OF column_name 
ON table_name
BEGIN
 -- Trigger logic goes here....
END;

实例

让我们假设一个情况,我们要为被插入到新创建的 COMPANY 表(如果已经存在,则删除重新创建)中的每一个记录保持审计试验:

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

为了保持审计试验,我们将创建一个名为 AUDIT 的新表。每当 COMPANY 表中有一个新的记录项时,日志消息将被插入其中:

sqlite> CREATE TABLE AUDIT(
    EMP_ID INT NOT NULL,
    ENTRY_DATE TEXT NOT NULL
);

在这里,ID 是 AUDIT 记录的 ID,EMP_ID 是来自 COMPANY 表的 ID,DATE 将保持 COMPANY 中记录被创建时的时间戳。所以,现在让我们在 COMPANY 表上创建一个触发器,如下所示:

sqlite> CREATE TRIGGER audit_log AFTER INSERT 
ON COMPANY
BEGIN
   INSERT INTO AUDIT(EMP_ID, ENTRY_DATE) VALUES (new.ID, datetime('now'));
END;

现在,我们将开始在 COMPANY 表中插入记录,这将导致在 AUDIT 表中创建一个审计日志记录。因此,让我们在 COMPANY 表中创建一个记录,如下所示:

sqlite> INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)
VALUES (1, 'Paul', 32, 'California', 20000.00 );

这将在 COMPANY 表中创建如下一个记录:

ID          NAME        AGE         ADDRESS     SALARY
----------  ----------  ----------  ----------  ----------
1           Paul        32          California  20000.0

同时,将在 AUDIT 表中创建一个记录。这个纪录是触发器的结果,这是我们在 COMPANY 表上的 INSERT 操作上创建的触发器(Trigger)。类似的,可以根据需要在 UPDATE 和 DELETE 操作上创建触发器(Trigger)。

EMP_ID      ENTRY_DATE
----------  -------------------
1           2013-04-05 06:26:00

列出触发器(TRIGGERS)

您可以从 sqlite_master 表中列出所有触发器,如下所示:

sqlite> SELECT name FROM sqlite_master
WHERE type = 'trigger';

上面的 SQLite 语句只会列出一个条目,如下:

name
----------
audit_log

如果您想要列出特定表上的触发器,则使用 AND 子句连接表名,如下所示:

sqlite> SELECT name FROM sqlite_master
WHERE type = 'trigger' AND tbl_name = 'COMPANY';

上面的 SQLite 语句只会列出一个条目,如下:

name
----------
audit_log

删除触发器(TRIGGERS)

下面是 DROP 命令,可用于删除已有的触发器:

sqlite> DROP TRIGGER trigger_name;

上面没有关于 for each row 和 when 的实例,这里补充一下。

for each row 是操作语句每影响到一行的时候就触发一次,也就是删了 10 行就触发 10 次,而 for each state 一条操作语句就触发一次,有时没有被影响的行也执行。sqlite 只实现了 for each row 的触发。when 和 for each row 用法是这样的:

CREATE TRIGGER trigger_name 
AFTER UPDATE OF id ON table_1 
FOR EACH ROW 
WHEN new.id>30 
BEGIN 
UPDATE table_2 SET id=new.id WHERE table_2.id=old.id;
END;

上面的触发器在 table_1 改 id 的时候如果新的 id>30 就把 表table_2 中和表table_1 id 相等的行一起改为新的 id

6、SQLite 索引(Index)

索引(Index)是一种特殊的查找表,数据库搜索引擎用来加快数据检索。简单地说,索引是一个指向表中数据的指针。一个数据库中的索引与一本书后边的索引是非常相似的。

例如,如果您想在一本讨论某个话题的书中引用所有页面,您首先需要指向索引,索引按字母顺序列出了所有主题,然后指向一个或多个特定的页码。

索引有助于加快 SELECT 查询和 WHERE 子句,但它会减慢使用 UPDATE 和 INSERT 语句时的数据输入。索引可以创建或删除,但不会影响数据。

使用 CREATE INDEX 语句创建索引,它允许命名索引,指定表及要索引的一列或多列,并指示索引是升序排列还是降序排列。

索引也可以是唯一的,与 UNIQUE 约束类似,在列上或列组合上防止重复条目。

CREATE INDEX 命令

CREATE INDEX 的基本语法如下:

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 子句中有两个或多个列经常使用,则选择使用组合索引。

隐式索引

隐式索引是在创建对象时,由数据库服务器自动创建的索引。索引自动创建为主键约束和唯一约束。

实例

下面是一个例子,我们将在 COMPANY 表的 salary 列上创建一个索引:

sqlite> CREATE INDEX salary_index ON COMPANY (salary);

现在,让我们使用 .indices 命令列出 COMPANY 表上所有可用的索引,如下所示:

sqlite> .indices COMPANY

这将产生如下结果,其中 sqlite_autoindex_COMPANY_1 是创建表时创建的隐式索引。

salary_index
sqlite_autoindex_COMPANY_1

您可以列出数据库范围的所有索引,如下所示:

sqlite> SELECT * FROM sqlite_master WHERE type = 'index';

DROP INDEX 命令

一个索引可以使用 SQLite 的 DROP 命令删除。当删除索引时应特别注意,因为性能可能会下降或提高。

基本语法如下:

DROP INDEX index_name;

您可以使用下面的语句来删除之前创建的索引:

sqlite> DROP INDEX salary_index;

什么情况下要避免使用索引?

虽然索引的目的在于提高数据库的性能,但这里有几个情况需要避免使用索引。使用索引时,应重新考虑下列准则:

  • 索引不应该使用在较小的表上。

  • 索引不应该使用在有频繁的大批量的更新或插入操作的表上。

  • 索引不应该使用在含有大量的 NULL 值的列上。

  • 索引不应该使用在频繁操作的列上。

7、SQLite Indexed By

"INDEXED BY index-name" 子句规定必须需要命名的索引来查找前面表中值。

如果索引名 index-name 不存在或不能用于查询,然后 SQLite 语句的准备失败。

"NOT INDEXED" 子句规定当访问前面的表(包括由 UNIQUE 和 PRIMARY KEY 约束创建的隐式索引)时,没有使用索引。

然而,即使指定了 "NOT INDEXED",INTEGER PRIMARY KEY 仍然可以被用于查找条目。

语法

下面是 INDEXED BY 子句的语法,它可以与 DELETE、UPDATE 或 SELECT 语句一起使用:

SELECT|DELETE|UPDATE column1, column2...
INDEXED BY (index_name)
table_name
WHERE (CONDITION);

实例

假设有表 COMPANY,我们将创建一个索引,并用它进行 INDEXED BY 操作。

sqlite> CREATE INDEX salary_index ON COMPANY(salary);
sqlite>

现在使用 INDEXED BY 子句从表 COMPANY 中选择数据,如下所示:

sqlite> SELECT * FROM COMPANY INDEXED BY salary_index WHERE salary > 5000;

8、SQLite Alter 命令

SQLite 的 ALTER TABLE 命令不通过执行一个完整的转储和数据的重载来修改已有的表。您可以使用 ALTER TABLE 语句重命名表,使用 ALTER TABLE 语句还可以在已有的表中添加额外的列。

在 SQLite 中,除了重命名表和在已有的表中添加列,ALTER TABLE 命令不支持其他操作。

语法

用来重命名已有的表的 ALTER TABLE 的基本语法如下:

ALTER TABLE database_name.table_name RENAME TO new_table_name;

用来在已有的表中添加一个新的列的 ALTER TABLE 的基本语法如下:

ALTER TABLE database_name.table_name ADD COLUMN column_def...;

实例

假设我们的 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

现在,让我们尝试使用 ALTER TABLE 语句重命名该表,如下所示:

sqlite> ALTER TABLE COMPANY RENAME TO OLD_COMPANY;

上面的 SQLite 语句将重命名 COMPANY 表为 OLD_COMPANY。现在,让我们尝试在 OLD_COMPANY 表中添加一个新的列,如下所示:

sqlite> ALTER TABLE OLD_COMPANY ADD COLUMN SEX char(1);

现在,COMPANY 表已经改变,使用 SELECT 语句输出如下:

ID          NAME        AGE         ADDRESS     SALARY      SEX
----------  ----------  ----------  ----------  ----------  ---
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

请注意,新添加的列是以 NULL 值来填充的。

9、SQLite Truncate Table

在 SQLite 中,并没有 TRUNCATE TABLE 命令,但可以使用 SQLite 的 DELETE 命令从已有的表中删除全部的数据,但建议使用 DROP TABLE 命令删除整个表,然后再重新创建一遍。

语法

DELETE 命令的基本语法如下:

sqlite> DELETE FROM table_name;

DROP TABLE 的基本语法如下:

sqlite> DROP TABLE table_name;

如果您使用 DELETE TABLE 命令删除所有记录,建议使用 VACUUM 命令清除未使用的空间。