SQLite 自带的 sqlite3 命令行工具很适合临时查数据、排查问题、导入导出小文件。下面整理一份常用命令,日常够用了。
启动和打开数据库
# 打开已有数据库;文件不存在时会自动创建
sqlite3 app.db
# 只读方式打开,适合线上排查
sqlite3 -readonly app.db
# 直接执行一条 SQL 后退出
sqlite3 app.db "select count(*) from users;"
# 打开内存数据库
sqlite3 :memory:
进入交互终端后,提示符一般是:
sqlite>
SQLite 终端里有两类命令:
- SQL 语句:例如
select * from users;,末尾需要分号。 - 点命令:例如
.tables、.schema,以.开头,不需要分号。
查看帮助和退出
.help -- 查看所有点命令
.quit -- 退出
.exit -- 退出
如果 SQL 写了一半进入了多行模式,可以用 Ctrl+C 取消当前输入。
查看数据库结构
.databases -- 查看当前连接的数据库文件
.tables -- 查看所有表
.tables user% -- 按模式过滤表名
.schema -- 查看完整建表语句
.schema users -- 查看某张表的建表语句
.indexes -- 查看所有索引
.indexes users -- 查看某张表的索引
也可以直接查系统表:
select name, type
from sqlite_master
where type in ('table', 'index', 'view')
order by type, name;
查看表字段:
pragma table_info(users);
查看外键:
pragma foreign_key_list(users);
输出格式设置
默认输出不太适合阅读,建议先打开表头和列模式:
.headers on
.mode column
select id, name, created_at from users limit 10;
常用输出模式:
.mode column -- 表格列对齐,适合人看
.mode box -- 边框表格,新版本 sqlite3 更好看
.mode list -- 默认模式
.mode csv -- CSV
.mode json -- JSON
.mode line -- 每列一行,适合字段很多的记录
设置空值显示:
.nullvalue NULL
打开 SQL 执行时间:
.timer on
常用查询
查看前几行:
select * from users limit 10;
按时间倒序:
select *
from users
order by created_at desc
limit 20;
统计行数:
select count(*) from users;
模糊搜索:
select *
from users
where name like '%tom%';
查看重复数据:
select email, count(*) as n
from users
group by email
having n > 1;
删除数据
删除前先查一遍,确认条件命中了正确的数据:
select *
from users
where id = 10;
删除一条记录:
delete from users
where id = 10;
按条件删除多条记录:
delete from users
where status = 'disabled';
删除前统计影响行数:
select count(*)
from users
where status = 'disabled';
更稳妥的做法是放进事务里:
begin;
delete from users
where status = 'disabled';
-- 确认删除后的结果
select count(*) from users;
commit;
如果发现删错了,在 commit; 之前可以回滚:
rollback;
清空整张表:
delete from users;
如果表有自增主键,并且想同时重置自增序列:
delete from users;
delete from sqlite_sequence where name = 'users';
SQLite 没有 MySQL 那种 truncate table users;,清空表一般就是用 delete from users;。
删除表结构和数据:
drop table users;
drop table 会把整张表删掉,表结构也没了,执行前最好先 .schema users 或 .dump users 留一份。
导入和导出
导出查询结果到 CSV
.headers on
.mode csv
.once users.csv
select id, name, email from users;
.once 只影响下一条 SQL。也可以用 .output 持续输出到文件:
.output users.csv
select * from users;
.output stdout
导入 CSV 到表
先确认表已经存在:
create table users_import (
id integer,
name text,
email text
);
再导入:
.mode csv
.import users.csv users_import
如果 CSV 第一行是表头,新版 sqlite3 可以这样跳过:
.import --skip 1 users.csv users_import
导出整个数据库
sqlite3 app.db ".dump" > app.sql
只导出某张表:
sqlite3 app.db ".dump users" > users.sql
从 SQL 文件恢复:
sqlite3 new.db < app.sql
备份和复制数据库
在 sqlite3 交互终端中备份:
.backup backup.db
把当前数据库保存为新文件:
.save copy.db
如果数据库正在被应用使用,优先用 .backup,不要直接复制 app.db 文件。
执行 SQL 文件
sqlite3 app.db < migration.sql
或在交互终端里执行:
.read migration.sql
事务操作
手动开启事务:
begin;
update users
set status = 'disabled'
where last_login_at < '2025-01-01';
commit;
发现不对就回滚:
rollback;
线上手动改数据时,建议先 begin;,查清影响范围后再 commit;。
查看执行计划
explain query plan
select *
from users
where email = 'a@example.com';
如果结果里看到全表扫描,并且这条查询很频繁,可以考虑加索引:
create index idx_users_email on users(email);
常用 PRAGMA
查看 SQLite 版本:
select sqlite_version();
查看数据库页大小和大小信息:
pragma page_size;
pragma page_count;
pragma freelist_count;
开启外键约束:
pragma foreign_keys = on;
查看外键是否开启:
pragma foreign_keys;
检查数据库完整性:
pragma integrity_check;
清理空间:
vacuum;
更新统计信息,帮助查询优化器:
analyze;
Attach 多个数据库
有时需要在两个 SQLite 数据库之间复制数据:
attach database 'old.db' as old;
insert into users (id, name, email)
select id, name, email
from old.users;
detach database old;
查看当前连接:
.databases
排查锁问题
如果遇到:
database is locked
可以先设置等待时间:
.timeout 5000
表示最多等待 5000 毫秒。
也可以检查当前 journal 模式:
pragma journal_mode;
开发环境可以考虑启用 WAL:
pragma journal_mode = wal;
WAL 通常能改善读写并发,但是否适合线上环境要结合部署方式判断,尤其是网络文件系统上要谨慎。
一个常用启动模板
平时查库可以这样开:
sqlite3 -readonly app.db
进入后先执行:
.headers on
.mode box
.timer on
.nullvalue NULL
.tables
如果 sqlite3 版本不支持 .mode box,就换成:
.mode column
小结
最常用的一组命令:
.help
.databases
.tables
.schema users
.headers on
.mode box
.timer on
.once result.csv
.import data.csv table_name
.backup backup.db
.read file.sql
.quit
记住点命令不加分号、SQL 语句要加分号,基本就能顺畅使用 sqlite3 终端了。