首页 / SQLite 入门教程 / 备份/恢复/导入导出

SQLite 入门教程

备份/恢复/导入导出

本教程共 50 篇 · 第 45 篇 · 更新于 2026-07-31

sqlite备份恢复CSV导入导出.dump

45. 备份/恢复/导入导出

本节目标:学完本章你能用文件复制、.dump/.restore、CSV 导入导出三种方式保全和迁移数据。

做数据库,最怕的不是写错一条 SQL,而是”库没了”。SQLite 是嵌入式、零配置(serverless)的数据库,没有独立服务进程,整个数据库就是一个普通的磁盘文件。这个特点带来一句朴素却极其重要的真理:复制这个文件,就是最原始、最可靠的备份

本章我们系统讲三种数据保全手段:直接复制文件、.dump/.restore 文本备份、以及 CSV 的导入导出。它们各有适用场景,掌握后你就再也不用担心”数据蒸发”。

方式一:复制文件即备份(最朴素也最稳)

既然数据库就是一个文件,那在没有任何写操作进行时,直接 cp(Linux/macOS)或 copy(Windows)拷贝这个 .db 文件,就能得到一份完全一致的备份:

cp myapp.db myapp.db.bak

这种方式的优点是:零学习成本、位级一致、速度快。缺点是:如果拷贝时正好有别的程序在写,可能拷到”写了一半”的状态。要保证一致性,最好先让库进入只读/无写状态,或用下面更稳妥的方案。

重点提示

“数据库即文件”是 SQLite 区别于 MySQL/PostgreSQL 这类客户机-服务器数据库的核心特征。后者要备份得用专门工具导出,而 SQLite 常常”复制走人”就行。这也是它适合嵌入式和单机场景的原因之一。

方式二:.dump 与 .read(文本备份与恢复)

.dump 把整个数据库的内容导出成一份纯 SQL 文本(建表语句 + 插入数据)。它不依赖”拷贝瞬间无写入”,因为它是通过 SQL 读取出来的,得到的是一份逻辑一致的快照:

sqlite3 myapp.db .dump > myapp.dump.sql

这份 .sql 文件可以用 gzip 压缩存档,体积小、还能跨机器、跨 SQLite 版本恢复,甚至能导入到其他支持 SQL 的数据库引擎:

sqlite3 newapp.db < myapp.dump.sql

在命令行交互界面里,恢复文本 dump 用 .read 命令(或前面那种输入重定向),把 .dump 出来的 SQL 文本重新执行一遍即可:

sqlite> .read myapp.dump.sql

重点提示

.dump 产出的是文本 SQL 文件,恢复它应当用 .read 或输入重定向(< file.sql),而不是 .restore.restore.backup 的配套命令,只能读取由 .backup 生成的二进制备份文件,用它去读文本 dump 会失败。文本 dump 的好处是”看得见、能跨版本跨引擎”,二进制备份的好处是”在线、原子、快”——两者适用场景不同,别混用。

实用技巧

推荐把 .dump 出来的文本再 gzip 压缩,既省空间又便携:

sqlite3 myapp.db .dump | gzip -c > myapp.dump.sql.gz
zcat myapp.dump.sql.gz | sqlite3 newapp.db

文本格式的额外好处是”看得见”——你可以用文本编辑器翻看里面到底备份了什么。

方式三:CSV 导入与导出(和表格软件互通)

实际工作中,数据常常要在 SQLite 和 Excel / 报表工具之间来回搬。CSV(Comma-Separated Values,逗号分隔值)就是最通用的桥梁。

导出为 CSV:先把输出模式设成 csv,再把结果定向到文件。注意我们示例表里的日期是用 TEXT 存的(SQLite 没有 DATE 类型,第 8、38 章讲过),所以 created_at 直接当文本导出即可:

sqlite> .mode csv --titles on
sqlite> .once orders_export.csv
sqlite> SELECT id, user_id, amount, created_at FROM orders;

.once 让下一条查询的输出写到指定文件而不是屏幕;--titles on 把列名作为 CSV 第一行。这样 orders_export.csv 就能直接拿 Excel 打开。

从 CSV 导入:用 .import 命令。假设有个 users_import.csv,第一行是列名:

sqlite> .mode csv
sqlite> .import --csv --skip 1 users_import.csv users

--skip 1 表示跳过 CSV 的第一行(表头)。SQLite 会按列顺序把数据塞进 users 表;若某列在 CSV 里缺失,则按表定义的默认值或 NULL 处理。

常见坑

导入前务必用 .mode csv--csv 指明输入格式,否则 CLI 会按当前输出模式去解释文件,导致字段错位、整行被当成一团文本。另外 CSV 是纯文本,不会保留类型——日期、数字导入后都先按文本进来,再按列的类型亲和性转换,这一点要心里有数。

命令行自带的备份命令:.backup / .clone / .save

除了”复制文件”,sqlite3 CLI 还提供在线备份相关命令,适合”库正在被使用”的场景:

  • .backup main backup.db —— 把当前数据库(main)在线备份到 backup.db
  • .restore main backup.db —— 反向操作,从二进制备份文件 backup.db 恢复到 main
  • .clone new.db —— 克隆一份当前库到 new.db
  • .save file.db —— 把内存库或当前改动写入文件(.backup 的别名)。

它们基于 SQLite 的在线备份机制,能在别的连接还在读写时,拷贝出一个一致的快照。第 44 章讲的 VACUUM INTO 'clean.db' 也兼具”备份 + 瘦身”的效果,可作为另一种选择。

外键与备份的一致性提醒

如果你的表用了真正的 REFERENCES 外键约束(比如 orders.user_id 引用 users.id),记住 SQLite 默认不强制外键,每次连接都需 PRAGMA foreign_keys = ON(第 13 章强调过)。在做恢复、导入这类批量写操作时,如果你希望参照完整性被检查,也要在会话里先打开它:

PRAGMA foreign_keys = ON;

否则即便导入了破坏引用关系的数据,SQLite 也不会报错,埋下后续查询”对不上号”的隐患。

常见坑

SQLite 默认不强制外键PRAGMA foreign_keys 默认 OFF),且它是连接级别开关,每次新连接(含重新打开 CLI)都要重新 PRAGMA foreign_keys = ON,不会持久记住。恢复、导入这类批量写操作前若不开它,破坏引用关系的数据会被悄悄写入而不报错,后续查询就可能”对不上号”。这与第 13 章强调的一致,务必在每次会做外键相关写的会话里主动开启。

实用技巧

备份策略小建议:日常用”复制文件”或 .backup 做快速快照;定期用 .dump 生成文本归档(方便跨版本、跨引擎迁移);和外部系统交换明细时用 CSV。三者互补,别只依赖其中一种。

恢复(Restore)的总体思路

“恢复”不外乎两件事:把备份弄回来、让它能被正常打开。

  • 文件级备份:直接用备份文件覆盖(或改名)回原路径即可。
  • .dump 文本备份:新建一个空库,把 .sql 灌进去(见上文 .restore / 重定向输入)。
  • CSV 备份:重新建表后 .import 进去;注意表结构得自己先建好,CSV 本身不含建表语句。

重点提示

任何恢复前,先用 PRAGMA integrity_check; 检查一下备份文件是否完好。损坏的备份比没有备份更危险,因为它会给你”已经安全了”的错觉。

类比小结

把数据保全想成”给重要文件上三道保险”:

  • 复制文件 = 把整本书 photocopy 一份放抽屉(快、一致,但怕拷到翻页瞬间);
  • .dump/.restore = 把书的内容手抄成一份纯文本稿(慢一点、但能跨版本跨机器、还能给人读);
  • CSV 导入导出 = 把书里的表格拆成 Excel 能读的格式,方便和外部系统对账。

三招齐备,SQLite 的数据就真正”丢不了”。至此,我们走完了”高级特性与维护”模块(第 42–45 章):从看懂查询计划、全文检索,到给库瘦身、再到备份导出,数据库的日常运维你已基本拿捏。下一篇进入”安全、生态与原理”模块,我们先聊最要命的 SQL 注入与参数化查询。