Article

关系型数据库SQLite

更新于:2026-07-16

第一章:SQLite 基础入门

1.1 SQLite 简介与特点

概念名称说明注意事项
嵌入式数据库SQLite 是一个无服务器、零配置、嵌入式的关系型数据库引擎,数据库以单个文件形式存储不支持多用户并发写入高负载场景
无独立服务进程不需要启动数据库服务,应用程序直接读写数据库文件适合移动端、桌面应用、测试环境
ACID 兼容支持原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)在 WAL 模式下并发读性能更优
跨平台支持 Windows、Linux、macOS、Android、iOS 等主流操作系统数据库文件可在不同平台间直接迁移
公共领域许可SQLite 源码属于公共领域(Public Domain),可自由用于商业和开源项目无需担心许可证合规问题
标准 SQL 支持支持大部分 SQL-92 标准,包括事务、触发器、视图、复合查询等不支持 RIGHT JOIN 和 FULL OUTER JOIN

1.2 安装与环境配置

步骤名称操作细节注意事项
Windows 安装1. 访问 https://www.sqlite.org/download.html
2. 下载 “Precompiled Binaries for Windows” 中的 sqlite-tools-win-x64.zip
3. 解压后将 sqlite3.exe 所在目录加入系统 PATH
若仅需使用命令行,无需安装额外依赖
macOS 安装通常已预装;若未安装,可通过 Homebrew 执行:brew install sqlite验证版本:sqlite3 --version
Linux 安装Ubuntu/Debian: sudo apt install sqlite3 sqlite3-dev
CentOS/RHEL: sudo yum install sqlite sqlite-devel
开发时如需编译 C 程序,需安装 -dev-devel
验证安装在终端执行:sqlite3 --version应显示版本号,如 3.45.0
环境变量配置sqlite3 可执行文件所在目录加入 PATH,确保全局可调用修改 PATH 后需重启终端或执行 source ~/.bashrc

1.3 命令行工具基本使用

命令/操作名称语法 / 使用方式用途代码示例注意事项
启动 SQLite CLIsqlite3 [数据库文件名]打开或创建数据库文件并进入交互模式sqlite3 test.db若文件不存在则自动创建
退出命令行.exit.quit退出 SQLite 命令行工具.exit也可使用 Ctrl+D(Linux/macOS)
执行 SQL 语句直接输入 SQL 语句,以分号结尾执行任意合法 SQLCREATE TABLE t(id INTEGER);
SELECT * FROM t;
必须以分号 ; 结束,否则视为语句未完成
查看帮助.help显示所有点命令(dot commands)说明.help点命令不以分号结尾
显示表列表.tables列出当前数据库中所有表名.tables仅显示用户表,不含系统表
查看表结构.schema [表名]显示建表语句.schema users若省略表名,则显示所有表的 schema
开启表头显示.headers on查询结果包含列名.headers on默认关闭,建议开启以便阅读输出
设置输出模式.mode list | column | table | csv | json控制查询结果格式.mode column常用 column 模式对齐列,csv 适合导出
执行 SQL 脚本.read 文件名从文件读取并执行 SQL 语句.read init.sql文件需包含有效 SQL,每条语句以分号结束

第二章:数据库与表操作

2.1 创建与连接数据库

操作名称操作细节用途代码示例注意事项
创建新数据库在命令行执行 sqlite3 后跟文件名创建并打开一个新数据库文件sqlite3 myapp.db若文件已存在则直接打开;路径可为相对或绝对
连接现有数据库同上,指定已有 .db.sqlite 文件打开已有数据库进行操作sqlite3 /path/to/existing.dbSQLite 不区分扩展名,但建议使用 .db.sqlite
内存数据库使用特殊文件名 :memory:创建临时内存数据库(程序退出后销毁)sqlite3 :memory:适用于测试或临时计算,无法持久化
验证当前数据库在 CLI 中执行 .database查看当前连接的数据库文件路径.database显示 main 数据库及其文件路径
自动创建机制首次写入操作(如建表)触发物理文件创建延迟创建数据库文件CREATE TABLE t(x); — 此时 my.db 才真正生成空数据库(无表)不会生成物理文件

2.2 创建、修改与删除表

操作名称语法用途代码示例注意事项
创建表CREATE TABLE 表名 (列定义 [, 约束])定义新表结构CREATE TABLE users(id INTEGER PRIMARY KEY, name TEXT NOT NULL);列类型为”亲和类型”,非强类型
添加列ALTER TABLE 表名 ADD COLUMN 列名 类型 [约束]向现有表新增一列ALTER TABLE users ADD COLUMN email TEXT;SQLite 仅支持 ADD COLUMN,不支持 DROP/RENAME COLUMN(旧版本)
重命名表ALTER TABLE 旧表名 RENAME TO 新表名修改表名称ALTER TABLE users RENAME TO accounts;所有依赖该表的对象(如视图)可能失效
删除表DROP TABLE [IF EXISTS] 表名永久删除整张表及其数据DROP TABLE IF EXISTS logs;无法恢复,谨慎操作;IF EXISTS 避免报错
限制说明SQLite 的 ALTER TABLE 功能有限仅支持重命名表和添加列如需复杂修改(如改列类型),需重建表:新建→迁移→删旧

重建表示例(间接修改列):

CREATE TABLE new_users(id INTEGER, full_name TEXT);
INSERT INTO new_users SELECT id, name FROM users;
DROP TABLE users;
ALTER TABLE new_users RENAME TO users;

2.3 表结构查看与元数据查询

操作名称语法 / 命令用途代码示例注意事项
查看所有表.tables列出当前数据库中所有用户表.tables不显示 sqlite_ 开头的系统表
查看特定表结构.schema 表名显示建表 SQL 语句.schema products若省略表名,显示全部表的 schema
查询表信息(SQL)SELECT * FROM sqlite_master WHERE type='table';通过 SQL 获取表元数据SELECT name, sql FROM sqlite_master WHERE type='table' AND name='users';sqlite_master 是元数据表,记录所有对象
查询列信息PRAGMA table_info(表名);获取表的列名、类型、是否为主键等PRAGMA table_info(users);返回字段:cid, name, type, notnull, dflt_value, pk
查看索引信息PRAGMA index_list(表名);列出某表上的所有索引PRAGMA index_list(users);可结合 PRAGMA index_info(index_name) 查看索引列
查看外键信息PRAGMA foreign_key_list(表名);显示表的外键约束定义PRAGMA foreign_key_list(orders);需确保外键支持已启用(默认关闭)
启用外键支持PRAGMA foreign_keys = ON;开启外键约束检查PRAGMA foreign_keys = ON;每次连接需重新设置,除非编译时默认开启

第三章:数据操作语言(DML)

3.1 插入数据(INSERT)

方法名称语法用途代码示例注意事项
基本插入INSERT INTO 表名 (列1, 列2, ...) VALUES (值1, 值2, ...);向表中插入一行数据INSERT INTO users (id, name) VALUES (1, 'Alice');列名可省略,但需按建表顺序提供全部值
多行插入INSERT INTO 表名 VALUES (...), (...), ...;一次插入多行INSERT INTO users VALUES (2, 'Bob'), (3, 'Carol');SQLite 3.7.11+ 支持此语法
插入默认值INSERT INTO 表名 DEFAULT VALUES;插入全为默认值的一行INSERT INTO logs DEFAULT VALUES;表必须所有列均有默认值或允许 NULL
从查询插入INSERT INTO 表名 SELECT ...;将查询结果插入目标表INSERT INTO backup_users SELECT * FROM users WHERE id > 10;目标表与 SELECT 列数和类型需兼容
忽略冲突插入INSERT OR IGNORE INTO 表名 ...;遇主键/唯一约束冲突时跳过INSERT OR IGNORE INTO users (id, name) VALUES (1, 'Duplicate');不报错,静默忽略冲突行
冲突替换插入INSERT OR REPLACE INTO 表名 ...;遇冲突时删除旧行并插入新行INSERT OR REPLACE INTO users (id, name) VALUES (1, 'Updated Alice');等效于”先删后插”,可能触发 DELETE 触发器

3.2 查询数据(SELECT)

方法名称语法用途代码示例注意事项
全表查询SELECT * FROM 表名;返回表中所有行和列SELECT * FROM users;生产环境慎用,性能差且冗余
指定列查询SELECT 列1, 列2 FROM 表名;仅返回指定列SELECT id, name FROM users;推荐明确指定列名
条件过滤SELECT ... FROM 表名 WHERE 条件;按条件筛选行SELECT * FROM users WHERE age >= 18;支持 AND/OR/NOT、LIKE、IN、BETWEEN 等
去重查询SELECT DISTINCT 列 FROM 表名;返回唯一值SELECT DISTINCT city FROM users;对组合列也适用:DISTINCT col1, col2
限制结果数量SELECT ... LIMIT 数量 [OFFSET 起始];分页或限制返回行数SELECT * FROM users LIMIT 5 OFFSET 10;OFFSET 从 0 开始;常用于分页
排序SELECT ... ORDER BY 列 [ASC|DESC];按列排序结果SELECT * FROM users ORDER BY name DESC;可多列排序:ORDER BY col1 ASC, col2 DESC
别名SELECT 列 AS 别名 FROM 表名;为列或表设置临时名称SELECT name AS username FROM users;AS 可省略,但建议保留以提高可读性

3.3 更新数据(UPDATE)

方法名称语法用途代码示例注意事项
基本更新UPDATE 表名 SET 列1=值1, 列2=值2 WHERE 条件;修改满足条件的行UPDATE users SET name='Alice Smith' WHERE id=1;必须加 WHERE,否则全表被更新
更新多列同上,在 SET 子句中逗号分隔多个赋值同时修改多个字段UPDATE users SET age=25, city='Beijing' WHERE id=1;所有赋值在同一事务中完成
使用子查询更新UPDATE 表名 SET 列=(SELECT ...) WHERE ...;根据其他表或聚合结果更新UPDATE orders SET total=(SELECT SUM(price) FROM items WHERE items.order_id=orders.id);子查询必须返回单值
忽略冲突更新UPDATE OR IGNORE 表名 SET ... WHERE ...;遇约束冲突时跳过该行UPDATE OR IGNORE users SET email='test@example.com' WHERE id=999;若 id=999 不存在,无影响;若更新违反 UNIQUE,跳过
替换式更新UPDATE OR REPLACE 表名 SET ... WHERE ...;遇唯一约束冲突时执行 REPLACE 逻辑(较少用,通常用 INSERT OR REPLACE)行为复杂,一般不推荐用于 UPDATE

3.4 删除数据(DELETE)

方法名称语法用途代码示例注意事项
条件删除DELETE FROM 表名 WHERE 条件;删除满足条件的行DELETE FROM users WHERE id=5;必须加 WHERE,否则删除全表数据
清空全表DELETE FROM 表名;删除表中所有数据DELETE FROM logs;保留表结构;比 DROP+CREATE 慢,因记录日志
快速清空(TRUNCATE)使用 VACUUM 或重建表实现高效清空大表(无直接 TRUNCATE 命令)
DELETE FROM t; VACUUM;
SQLite 无 TRUNCATE 语句,DELETE + VACUUM 可释放空间
带子查询删除DELETE FROM 表名 WHERE 列 IN (SELECT ...);根据子查询结果删除DELETE FROM orders WHERE user_id NOT IN (SELECT id FROM users);子查询应返回单列值列表
安全删除建议先 SELECT 验证条件避免误删SELECT * FROM users WHERE status='inactive';
— 确认后再 DELETE
强烈建议在 DELETE 前先用相同 WHERE 做 SELECT 验证

第四章:查询进阶与函数

4.1 条件查询与排序(WHERE, ORDER BY)

操作名称语法用途代码示例注意事项
基本条件过滤WHERE 列 比较运算符 值筛选满足条件的行SELECT * FROM products WHERE price > 100;支持 =, !=, <, <=, >, >=
多条件组合WHERE 条件1 AND/OR 条件2组合多个筛选条件SELECT * FROM users WHERE age >= 18 AND city = 'Shanghai';注意 AND 优先级高于 OR,必要时用括号
范围查询WHERE 列 BETWEEN 值1 AND 值2查询某范围内的值SELECT * FROM orders WHERE amount BETWEEN 50 AND 200;包含边界值
成员判断WHERE 列 IN (值1, 值2, ...)判断列值是否在给定集合中SELECT * FROM users WHERE role IN ('admin', 'editor');可替换为多个 OR,但 IN 更简洁
模糊匹配WHERE 列 LIKE '模式'字符串模糊匹配SELECT * FROM users WHERE name LIKE 'A%';% 表示任意字符(包括空),_ 表示单个字符
空值判断WHERE 列 IS NULL / IS NOT NULL判断是否为空SELECT * FROM users WHERE email IS NULL;不能用 = NULL,必须用 IS NULL
升序/降序排序ORDER BY 列 [ASC | DESC]对结果集排序SELECT * FROM products ORDER BY price DESC;默认 ASC(升序);可多列排序
按表达式排序ORDER BY 表达式按计算结果排序SELECT name, salary*12 AS annual FROM employees ORDER BY annual DESC;表达式或别名可用于 ORDER BY

4.2 聚合函数与分组(GROUP BY, HAVING)

操作名称语法用途代码示例注意事项
计数COUNT(*)COUNT(列)统计行数SELECT COUNT(*) FROM users;COUNT(*) 包含 NULL 行;COUNT(列) 忽略 NULL
求和SUM(列)对数值列求和SELECT SUM(amount) FROM orders;非数值列返回 0 或 NULL
平均值AVG(列)计算平均值SELECT AVG(score) FROM exams;自动忽略 NULL 值
最大/最小值MAX(列) / MIN(列)获取最大或最小值SELECT MAX(price), MIN(price) FROM products;适用于数值、日期、字符串
分组统计SELECT 聚合函数 FROM 表 GROUP BY 列按列分组后聚合SELECT city, COUNT(*) FROM users GROUP BY city;SELECT 中非聚合列必须出现在 GROUP BY 中
分组后过滤HAVING 聚合条件对分组结果进行筛选SELECT city, COUNT(*) FROM users GROUP BY city HAVING COUNT(*) > 5;WHERE 用于行过滤,HAVING 用于组过滤
多列分组GROUP BY 列1, 列2按多列组合分组SELECT dept, role, AVG(salary) FROM staff GROUP BY dept, role;分组粒度更细

4.3 连接查询(JOIN)

操作名称语法用途代码示例注意事项
内连接(INNER JOIN)SELECT ... FROM A INNER JOIN B ON A.id = B.a_id返回两表匹配的行SELECT u.name, o.amount FROM users u INNER JOIN orders o ON u.id = o.user_id;可简写为 JOIN,默认即 INNER
左外连接(LEFT JOIN)SELECT ... FROM A LEFT JOIN B ON A.id = B.a_id返回左表全部行,右表无匹配则 NULLSELECT u.name, o.amount FROM users u LEFT JOIN orders o ON u.id = o.user_id;SQLite 不支持 RIGHT/FULL OUTER JOIN
自连接SELECT ... FROM 表 A JOIN 表 B ON A.列 = B.列同一表内关联(如上下级关系)SELECT e.name, m.name AS manager FROM emp e LEFT JOIN emp m ON e.manager_id = m.id;需使用别名区分同一表的不同实例
使用 USINGSELECT ... FROM A JOIN B USING (公共列名)简化等值连接写法SELECT * FROM orders JOIN customers USING (customer_id);要求两表有同名列;结果中该列只出现一次
多表连接SELECT ... FROM A JOIN B ON ... JOIN C ON ...连接三个及以上表SELECT u.name, p.title, o.date FROM users u JOIN orders o ON u.id=o.user_id JOIN products p ON o.product_id=p.id;注意连接顺序和性能

4.4 内置函数(字符串、日期、数学等)

函数类别函数名称语法用途代码示例注意事项
字符串LENGTH(str)LENGTH(列或字符串)返回字符串字节长度SELECT LENGTH(name) FROM users;UTF-8 下中文字符占 3 字节
字符串UPPER(str)UPPER(列)转大写SELECT UPPER(name) FROM users;仅处理 ASCII 字母,除非编译时启用 ICU
字符串LOWER(str)LOWER(列)转小写SELECT LOWER(email) FROM users;同上
字符串SUBSTR(str, start, len)SUBSTR(列, 起始, 长度)截取子串(起始从 1 开始)SELECT SUBSTR(phone, 1, 3) FROM contacts;起始为负数表示从末尾开始
字符串REPLACE(str, old, new)REPLACE(列, 旧, 新)替换子串SELECT REPLACE(description, 'old', 'new') FROM items;全局替换
日期DATE(‘now’)DATE(表达式)获取当前日期(YYYY-MM-DD)SELECT DATE('now');支持 '+1 day', '-1 month' 等修饰符
日期DATETIME(‘now’)DATETIME(表达式)获取当前日期时间SELECT DATETIME('now', 'localtime');'localtime' 转为本地时区
日期STRFTIME(fmt, t)STRFTIME('%Y-%m', 'now')格式化日期SELECT STRFTIME('%Y年%m月', created_at) FROM logs;类似 strftime C 函数
数学ABS(x)ABS(数值)绝对值SELECT ABS(-10);
数学ROUND(x, d)ROUND(数值, 小数位)四舍五入SELECT ROUND(price, 2) FROM products;d 默认为 0
数学RANDOM()RANDOM()返回随机整数SELECT RANDOM() % 100; — 生成 0-99 随机数用于测试或简单随机抽样
类型TYPEOF(x)TYPEOF(列或值)返回存储类型(null, integer, real, text, blob)SELECT TYPEOF(name) FROM users;反映 SQLite 实际存储类型,非声明类型

第五章:约束、索引与事务

5.1 主键、外键与唯一性约束

约束类型语法 / 定义方式用途代码示例注意事项
主键(PRIMARY KEY)列定义中添加 PRIMARY KEY,或表级约束唯一标识每一行,隐含 NOT NULLCREATE TABLE users(id INTEGER PRIMARY KEY, name TEXT);SQLite 中 INTEGER PRIMARY KEY 自动成为 rowid 别名,性能更优
复合主键PRIMARY KEY (列1, 列2)多列联合唯一标识CREATE TABLE order_items(order_id INT, product_id INT, PRIMARY KEY(order_id, product_id));不能包含 NULL(因主键隐含 NOT NULL)
唯一性约束(UNIQUE)列级:列名 类型 UNIQUE
表级:UNIQUE (列1, 列2)
保证列或列组合值唯一CREATE TABLE emails(email TEXT UNIQUE);允许存在多个 NULL(SQLite 视 NULL 为不相等)
外键约束(FOREIGN KEY)FOREIGN KEY (列) REFERENCES 主表(主键列) [ON DELETE/UPDATE 动作]维护引用完整性CREATE TABLE orders(user_id INT, FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE);默认关闭,需执行 PRAGMA foreign_keys = ON; 才生效
外键动作ON DELETE SET NULL / CASCADE / RESTRICT / NO ACTION定义主表删除时从表行为FOREIGN KEY(dept_id) REFERENCES depts(id) ON DELETE SET NULLCASCADE 表示级联删除;SET NULL 需从表列允许 NULL
启用外键PRAGMA foreign_keys = ON;全局开启外键检查PRAGMA foreign_keys = ON;每次连接数据库后需重新设置(除非编译时默认开启)

5.2 默认值、非空与检查约束

约束类型语法 / 定义方式用途代码示例注意事项
默认值(DEFAULT)列定义中添加 DEFAULT 值插入时若未提供值则使用默认值CREATE TABLE logs(msg TEXT, created_at TEXT DEFAULT (DATETIME('now')));默认值可为常量或函数(如 CURRENT_TIME、RANDOM())
非空约束(NOT NULL)列定义中添加 NOT NULL禁止该列为空CREATE TABLE users(name TEXT NOT NULL);插入或更新时若为 NULL 将报错
检查约束(CHECK)列级:CHECK (条件)
表级:CHECK (条件)
限制列值必须满足逻辑条件CREATE TABLE products(price REAL CHECK (price > 0));条件为布尔表达式;插入/更新时验证
多条件 CHECKCHECK (age >= 0 AND age <= 150)组合多个验证逻辑CREATE TABLE persons(age INT CHECK (age BETWEEN 0 AND 150));可引用同一行的其他列
约束命名CONSTRAINT 名称 约束为约束指定名称(便于调试)CREATE TABLE t(x INT CONSTRAINT positive_x CHECK (x > 0));SQLite 支持但不强制使用;错误信息中会显示名称

5.3 创建与管理索引

操作名称语法用途代码示例注意事项
创建普通索引CREATE INDEX 索引名 ON 表名(列1, 列2);加速 WHERE、ORDER BY 查询CREATE INDEX idx_users_city ON users(city);索引名需唯一;多列索引顺序影响查询效率
创建唯一索引CREATE UNIQUE INDEX 索引名 ON 表名(列);强制列值唯一并加速查询CREATE UNIQUE INDEX idx_emails_email ON emails(email);插入重复值时报错
查看索引.indexes [表名]PRAGMA index_list(表名);列出表上的所有索引.indexes users.indexes 为 CLI 命令;PRAGMA 可在 SQL 中使用
删除索引DROP INDEX 索引名;移除不再需要的索引DROP INDEX idx_users_city;不影响表数据,仅移除索引结构
部分索引(Partial Index)CREATE INDEX ... WHERE 条件仅对满足条件的行建索引CREATE INDEX idx_active_users ON users(id) WHERE status = 'active';SQLite 3.8.0+ 支持;节省空间,提升特定查询性能
索引使用建议在高频查询的 WHERE、JOIN、ORDER BY 列上建索引优化查询性能过多索引会降低 INSERT/UPDATE/DELETE 性能;避免在低区分度列(如性别)建索引

5.4 事务控制(BEGIN, COMMIT, ROLLBACK)

操作名称语法用途代码示例注意事项
开启事务BEGIN [DEFERRED | IMMEDIATE | EXCLUSIVE];显式启动一个事务BEGIN IMMEDIATE;默认为 DEFERRED(延迟加锁);IMMEDIATE 立即获取保留锁
提交事务COMMIT;永久保存事务中所有更改COMMIT;等价于 END TRANSACTION;
回滚事务ROLLBACK;撤销事务中所有未提交的更改ROLLBACK;数据恢复到 BEGIN 前状态
自动提交模式每条 DML 语句自动包裹在独立事务中默认行为INSERT INTO t VALUES (1); — 自动 COMMIT性能差,批量操作应显式使用事务
保存点(SAVEPOINT)SAVEPOINT 名称; ... ROLLBACK TO 名称; RELEASE 名称;在事务内设置回滚点SAVEPOINT sp1;
INSERT INTO t VALUES (2);
ROLLBACK TO sp1;
SQLite 3.6.8+ 支持;支持嵌套
WAL 模式与事务PRAGMA journal_mode = WAL;启用写前日志模式,提升并发读性能PRAGMA journal_mode = WAL;事务行为不变,但允许多个读 + 一个写并发

批量操作事务示例:

BEGIN;
INSERT INTO logs VALUES ('a');
INSERT INTO logs VALUES ('b');
COMMIT;

第六章:SQLite 命令行高级操作

6.1 导入与导出数据(.import / .output / .dump)

操作名称语法 / 命令用途代码示例注意事项
导出为 SQL 脚本.dump [表名]生成可重建数据库的完整 SQL 脚本.dump users若省略表名,则导出整个数据库;包含表结构和数据
导出查询结果.output 文件名
SELECT ...;
.output stdout
将查询结果写入文件.output report.txt
SELECT * FROM sales;
.output stdout
默认输出格式受 .mode 影响;记得恢复 stdout
导入 CSV/TSV 数据.mode csv.mode tabs
.import 文件名 表名
从分隔文件批量导入数据.mode csv
.import data.csv users
表必须已存在;首行为列名时需跳过或预处理
导出为 CSV.headers on
.mode csv
.output file.csv
SELECT * FROM t;
生成标准 CSV 文件.headers on
.mode csv
.output users.csv
SELECT * FROM users;
推荐用于与其他系统交换数据
备份数据库sqlite3 原库.db .dump > backup.sql在 shell 中直接导出sqlite3 app.db .dump > app_backup.sql可跨平台恢复;文本格式便于版本控制
导入注意事项确保目标表结构与文件列数匹配避免导入失败.import 不自动创建表;不处理引号内换行(简单解析)

6.2 格式化输出与模式切换(.mode / .headers / .width)

操作名称语法 / 命令用途代码示例注意事项
切换输出模式.mode 模式名控制查询结果展示格式.mode column支持:column, list, csv, table, json, line, tabs 等
开启列标题.headers on | off是否在结果中显示列名.headers on默认 off;建议开启以便阅读
设置列宽.width 宽度1 宽度2 ...手动指定各列显示宽度(仅 column 模式).width 5 15 10
SELECT id, name, email FROM users;
超出宽度会截断;负数表示左对齐
表格模式美化.mode table以 ASCII 表格形式输出.mode table
SELECT * FROM products;
自动对齐,视觉清晰,适合终端查看
行模式输出.mode line每列一行,格式:列名 = 值.mode line
SELECT * FROM users WHERE id=1;
适合查看单行详细信息
JSON 输出.mode json将结果输出为 JSON 数组.mode json
SELECT id, name FROM users LIMIT 2;
SQLite 3.38.0+ 支持;便于程序解析

6.3 数据库信息查看(.tables / .schema / .database)

操作名称语法 / 命令用途代码示例注意事项
列出所有表.tables [匹配模式]显示当前数据库中的用户表.tables支持通配符:.tables user% → 匹配 user 开头的表
查看建表语句.schema [表名]显示表的 CREATE TABLE 语句.schema orders若省略表名,显示所有表、索引、触发器的定义
查看数据库路径.database显示当前连接的数据库文件信息.database输出 main 和 temp 数据库的文件路径
查看索引.indexes [表名]列出指定表的所有索引.indexes users若省略表名,列出所有索引
查看视图定义SELECT sql FROM sqlite_master WHERE type='view' AND name='视图名';获取视图的 SELECT 语句SELECT sql FROM sqlite_master WHERE name='active_users';视图定义存储在 sqlite_master 表中
查看触发器.schema 触发器名 或查询 sqlite_master显示触发器定义SELECT sql FROM sqlite_master WHERE type='trigger';.schema 也可用于触发器

6.4 执行脚本与批处理(.read / .load)

操作名称语法 / 命令用途代码示例注意事项
执行 SQL 脚本.read 文件名从文件读取并执行 SQL 语句.read init_db.sql文件中每条 SQL 必须以分号 ; 结尾
加载扩展模块.load 文件名 [入口函数]动态加载 C 编写的 SQLite 扩展.load ./spellfix.so需编译为共享库;入口函数默认为 sqlite3_extension_init
错误处理脚本中某条语句失败,默认继续执行需人工检查日志可在脚本开头加 .bail on 使出错即退出
启用错误立即退出.bail on遇 SQL 错误立即终止.bail on
.read risky_script.sql
默认 .bail off;调试脚本时建议开启
注释支持SQL 脚本中可使用 -- 单行注释 或 /* ... */ 多行注释提高脚本可读性-- 创建用户表
CREATE TABLE users (...);
CLI 和 .read 均支持标准 SQL 注释

批量初始化示例:

创建 init.sql

CREATE TABLE t(...);
INSERT INTO t VALUES (...);

然后执行 .read init.sql

第七章:性能与维护

7.1 VACUUM 与数据库压缩

操作名称语法 / 命令用途代码示例注意事项
执行 VACUUMVACUUM;重建数据库文件,释放未使用空间VACUUM;会创建临时副本,需足够磁盘空间;耗时较长
指定 VACUUM 到新文件VACUUM INTO '新文件路径';将压缩后的数据库写入新文件VACUUM INTO 'backup_compact.db';SQLite 3.27.0+ 支持;原库不变,适合在线备份
自动 VACUUM 模式PRAGMA auto_vacuum = [NONE | FULL | INCREMENTAL];控制删除数据后是否自动回收空间PRAGMA auto_vacuum = INCREMENTAL;默认为 NONE;FULL 模式在事务提交时自动整理,但仍有碎片;INCREMENTAL 需配合 PRAGMA incremental_vacuum(n) 手动触发
查看当前模式PRAGMA auto_vacuum;查询当前 auto_vacuum 设置PRAGMA auto_vacuum;返回 0=NONE, 1=FULL, 2=INCREMENTAL
使用建议定期对频繁 UPDATE/DELETE 的数据库执行 VACUUM防止数据库文件无限膨胀移动端或嵌入式设备存储有限时尤为重要

7.2 分析与优化查询(EXPLAIN QUERY PLAN)

操作名称语法 / 命令用途代码示例注意事项
查看执行计划EXPLAIN QUERY PLAN SELECT ...;显示 SQLite 如何执行查询EXPLAIN QUERY PLAN SELECT * FROM users WHERE id=1;输出包含搜索方式(SCAN/TABLE/INDEX)、是否使用索引等
计划解读关键词SEARCH TABLE ... USING INDEX ...
SCAN TABLE ...
判断是否高效使用索引SEARCH TABLE users USING INTEGER PRIMARY KEY (rowid=?)”SEARCH” 表示使用索引;“SCAN” 表示全表扫描,应避免
强制忽略索引SELECT * FROM t INDEXED BY 索引名 WHERE ...指定使用某索引SELECT * FROM users INDEXED BY idx_city WHERE city='BJ';调试时验证索引效果;一般不用于生产
统计信息更新ANALYZE;收集表和索引的统计信息供优化器使用ANALYZE;首次建索引后建议执行;统计信息存于 sqlite_stat1
查看统计信息SELECT * FROM sqlite_stat1;检查优化器使用的采样数据SELECT * FROM sqlite_stat1;若表数据分布变化大,需重新 ANALYZE
优化建议对 WHERE、JOIN、ORDER BY 中的列建立合适索引减少全表扫描复合索引顺序应匹配查询条件顺序

7.3 WAL 模式与并发控制

操作名称语法 / 命令用途代码示例注意事项
启用 WAL 模式PRAGMA journal_mode = WAL;切换到写前日志(Write-Ahead Logging)模式PRAGMA journal_mode = WAL;返回 “wal” 表示成功;提升读并发性能
查看当前日志模式PRAGMA journal_mode;查询当前 journal modePRAGMA journal_mode;可能返回 delete(默认)、wal、memory 等
WAL 优势允许多个 reader + 一个 writer 并发避免写操作阻塞读传统 rollback 模式下写会锁全库
WAL 文件数据库同目录生成 .db-wal.db-shm 文件存储未 checkpoint 的事务日志不要手动删除 .wal/.shm 文件,否则可能丢数据
强制 CheckpointPRAGMA wal_checkpoint;将 WAL 日志写回主数据库文件PRAGMA wal_checkpoint;自动 checkpoint 由 SQLite 触发(如 WAL 达 1000 页)
禁用 WALPRAGMA journal_mode = DELETE;切回默认日志模式PRAGMA journal_mode = DELETE;切换时会自动执行 checkpoint
使用建议高读低写场景(如 Web 应用、日志系统)推荐启用 WAL提升响应速度不适用于 NFS 等不支持共享内存的文件系统

7.4 备份与恢复策略

操作名称方法 / 命令用途代码示例 / 操作步骤注意事项
在线备份(SQL dump)sqlite3 db.db .dump > backup.sql生成可移植的文本备份sqlite3 app.db .dump > app_20250405.sql可跨版本、跨平台恢复;但大数据量时慢
在线备份(VACUUM INTO)VACUUM INTO 'backup.db';快速生成压缩后的二进制备份VACUUM INTO 'safe_copy.db';SQLite 3.27.0+;备份期间原库可读写
冷备份直接复制 .db 文件最简单备份方式cp myapp.db myapp_backup.db必须确保无写入进程,否则可能损坏
热备份(WAL 模式)复制 .db + .db-wal + .db-shm(需原子性)WAL 模式下的安全热备实际操作复杂;推荐用 .dumpVACUUM INTO
恢复数据库sqlite3 new.db < backup.sql从 SQL 脚本恢复sqlite3 restored.db < app_backup.sql新数据库自动创建;注意字符编码
增量备份策略定期 .dump + 记录最后备份时间戳,结合应用层日志减少备份体积SQLite 无内置 binlog,需应用层配合
备份验证恢复到临时库并执行 .tables / COUNT(*)确保备份完整可用sqlite3 test.db < backup.sql && sqlite3 test.db "SELECT COUNT(*) FROM users;"关键业务必须验证备份有效性

第八章:SQLite 应用集成(简要)

8.1 在 Python 中使用 SQLite(sqlite3 模块)

方法/操作名称语法 / 使用方式用途代码示例注意事项
连接数据库sqlite3.connect(数据库路径)打开或创建数据库连接conn = sqlite3.connect('app.db')路径可为文件名或 ':memory:'(内存库)
创建游标conn.cursor()获取执行 SQL 的游标对象cur = conn.cursor()游标用于执行查询和获取结果
执行 SQLcur.execute(sql, [参数])执行单条 SQL 语句cur.execute("INSERT INTO users (name) VALUES (?)", ("Alice",))使用 ? 占位符防 SQL 注入;不可拼接字符串
批量执行cur.executemany(sql, 参数序列)高效插入/更新多行cur.executemany("INSERT INTO t (x) VALUES (?)", [(1,), (2,)])自动开启事务,性能优于循环 execute
提交事务conn.commit()永久保存更改conn.commit()默认自动提交关闭,需显式 commit
查询结果获取cur.fetchall() / fetchone() / fetchmany(n)获取 SELECT 结果rows = cur.execute("SELECT * FROM users").fetchall()fetchall() 返回列表;大数据量建议分批 fetch
关闭连接conn.close()释放数据库连接conn.close()建议在 finally 块或使用 with 语句管理
上下文管理器with sqlite3.connect(...) as conn: ...自动提交或回滚with sqlite3.connect('db.db') as conn:
conn.execute("...")
正常退出自动 commit,异常自动 rollback

8.2 在 C/C++ 中嵌入 SQLite

操作名称语法 / 函数调用用途代码示例(C 风格)注意事项
初始化与打开sqlite3_open(const char *filename, sqlite3 **ppDb)打开数据库连接sqlite3 *db;
int rc = sqlite3_open("test.db", &db);
返回 SQLITE_OK 表示成功;需链接 -lsqlite3
执行无结果 SQLsqlite3_exec(db, sql, callback, data, &errMsg)执行 CREATE/INSERT/UPDATE 等sqlite3_exec(db, "CREATE TABLE t(x);", 0, 0, &err);callback 为 NULL 时忽略结果;错误信息需 free(errMsg)
编译 SQL 语句sqlite3_prepare_v2(db, sql, -1, &stmt, 0)预编译带参数的 SQLsqlite3_prepare_v2(db, "INSERT INTO t VALUES (?)", -1, &stmt, 0);推荐使用 prepare_v2 而非 v1
绑定参数sqlite3_bind_text(stmt, idx, val, len, SQLITE_STATIC)为预编译语句绑定参数sqlite3_bind_text(stmt, 1, "hello", -1, SQLITE_TRANSIENT);idx 从 1 开始;SQLITE_TRANSIENT 表示复制字符串
执行预编译语句sqlite3_step(stmt)执行一条预编译语句sqlite3_step(stmt);返回 SQLITE_DONE(DML)或 SQLITE_ROW(有结果)
获取查询结果sqlite3_column_text(stmt, colIndex)从当前行获取列值const char *name = (const char *)sqlite3_column_text(stmt, 0);需先调用 sqlite3_step() 获取行
重置与释放sqlite3_reset(stmt); sqlite3_finalize(stmt);复用或销毁语句对象sqlite3_reset(stmt); // 可再次 bind 和 stepfinalize 释放资源;reset 保留编译状态
关闭数据库sqlite3_close(db)关闭连接并释放资源sqlite3_close(db);确保所有 stmt 已 finalize

8.3 与其他语言/框架的集成要点

语言/框架集成方式 / 核心库用途典型用法示例注意事项
JavaScript (Node.js)使用 better-sqlite3sqlite3 npm 包后端或 Electron 应用嵌入数据库const db = new Database('app.db'); db.prepare("SELECT ...").all();better-sqlite3 性能更高,同步 API;sqlite3 包支持异步
Java使用 org.xerial:sqlite-jdbcAndroid 或桌面 Java 应用Connection conn = DriverManager.getConnection("jdbc:sqlite:test.db");需将 sqlite-jdbc.jar 加入 classpath
Go使用 modernc.org/sqlitego-sqlite3Go 应用内嵌数据库db, _ := sql.Open("sqlite", "file:test.db?cache=shared&mode=rwc")modernc.org/sqlite 是纯 Go 实现,无需 CGO
.NET (C#)使用 Microsoft.Data.SqliteSystem.Data.SQLiteWindows 桌面或 ASP.NET Coreusing var conn = new SqliteConnection("Data Source=app.db;");Microsoft.Data.Sqlite 是官方轻量驱动
Rust使用 rusqlite crate系统级应用或 CLI 工具let conn = Connection::open("app.db")?; conn.execute("...", params![])?;基于 libsqlite3,需系统安装或静态链接
Web 浏览器使用 sql.js(基于 Emscripten 编译的 SQLite)前端浏览器内运行 SQLiteconst db = new SQL.Database(); db.run("CREATE TABLE t(x);");数据库存在于内存,刷新丢失;适合离线演示

通用集成原则:

  1. 使用参数化查询 — 保证安全与稳定性
  2. 管理连接生命周期
  3. 处理并发写限制 — SQLite 不适合高并发写场景;多进程访问需谨慎(建议 WAL + 文件锁)