Skip to content

第一章 认识 SQLite


1.1 SQLite 是什么 —— 一句话理解

SQLite = 一个嵌入在你的应用程序里的关系型数据库引擎。

和 MySQL、PostgreSQL 不同,SQLite 没有独立的服务器进程,它直接以 库(Library) 的形式链接到你的程序中。整个数据库就是磁盘上的一个文件,不需要安装、不需要配置、不需要启动服务——import sqlite3 就能用。

┌─────────────────────────────────────────┐
│           你的应用程序                    │
│                                         │
│   ┌───────────────────────────────┐     │
│   │        SQLite 引擎            │     │
│   │  (直接链接在进程内部)         │     │
│   │                               │     │
│   │   SQL 解析 → 虚拟机执行       │     │
│   │   → B-Tree 存储 → 文件 I/O   │     │
│   └───────────┬───────────────────┘     │
│               │                         │
└───────────────┼─────────────────────────┘


        ┌──────────────┐
        │  database.db  │  ← 整个数据库就是一个文件
        │  (磁盘文件)  │
        └──────────────┘

它有多普及?看一组数据:

指标数字
全球活跃部署量超过 1 万亿个
你手机里有几个 SQLite 数据库平均 数百个
内置 SQLite 的系统/软件Android、iOS、Chrome、Firefox、微信、Telegram……
代码量约 15 万行 C 代码(含注释约 100 万行测试代码)

一句话概括:SQLite 是世界上部署量最大的数据库引擎——不是之一。每一台智能手机、每一个浏览器、每一个操作系统里,都有它的身影。


1.2 SQLite 的设计哲学

SQLite 的创造者 D. Richard Hipp 为它确立了几个核心设计原则,理解这些原则能帮你判断什么时候该用它、什么时候不该用。

零配置(Zero-Configuration)

不需要 my.cnf、不需要 postgresql.conf、不需要设置用户名密码。打开文件就是打开数据库,关闭文件就结束了。

python
import sqlite3

# 这一行就创建了一个完整的关系型数据库
conn = sqlite3.connect("my_app.db")

没有 DBA(数据库管理员),没有配置调优,做到了真正的开箱即用

无服务器(Serverless)

传统数据库的架构是 客户端-服务器 模式:

传统数据库(MySQL / PostgreSQL):
┌────────┐          ┌────────────┐          ┌────────┐
│ 客户端  │ ──TCP──→ │ 数据库服务器 │ ──读写──→ │  磁盘  │
│ (应用)  │ ←─TCP── │  (独立进程)  │ ←─读写── │  文件  │
└────────┘          └────────────┘          └────────┘

SQLite:
┌──────────────────────┐          ┌────────┐
│ 应用程序              │          │        │
│   ┌──────────────┐   │ ──读写──→│  磁盘  │
│   │ SQLite (库)   │   │ ←─读写──│  文件  │
│   └──────────────┘   │          │        │
└──────────────────────┘          └────────┘

少了一层网络通信,少了一个独立进程。

SQLite 直接通过文件系统 API 读写磁盘,没有网络通信开销,没有进程间通信开销。

单文件(Single-File)

一个 SQLite 数据库 = 一个磁盘文件。这意味着:

  • 备份cp database.db database_backup.db
  • 迁移:把文件复制到另一台机器就行
  • 版本控制:可以和代码一起提交(小型数据库)
  • 跨平台:同一个 .db 文件可以在 Windows、macOS、Linux 之间无缝使用

自包含(Self-Contained)

SQLite 的所有功能都打包在一个 C 源文件(sqlite3.c,约 25 万行)里。没有外部依赖,不需要额外安装任何东西。这让它可以轻松嵌入到任何环境中——从嵌入式设备到航天飞机。

设计理念总结:SQLite 的目标不是替代 MySQL / PostgreSQL,而是替代 fopen()。它解决的核心问题是:让应用程序以 SQL 的方式管理本地数据,而不是自己去解析文本文件或二进制格式。


1.3 SQLite 能解决什么问题

SQLite 不是万能的,但在以下场景中它是最佳选择:

场景一:移动端 & 嵌入式应用

这是 SQLite 最经典的战场。Android 和 iOS 都内置了 SQLite 作为本地数据存储方案。你手机里的通讯录、短信、照片元数据、App 缓存——绝大多数都躺在 SQLite 数据库里。

┌──────────────┐     ┌──────────────┐
│   App 界面    │     │   SQLite DB   │
│  (展示数据)   │────→│  contacts.db  │
│              │←────│  messages.db  │
└──────────────┘     └──────────────┘
不需要网络,不需要服务器,离线也能用。

场景二:桌面应用的本地存储

浏览器(Chrome、Firefox)用 SQLite 存储历史记录、书签、Cookie。微信桌面版用它存聊天记录。只要你的应用需要在本地存储结构化数据,SQLite 就是最省心的选择。

场景三:应用缓存与中间数据

Web 框架(如 Django)默认使用 SQLite 作为开发环境的数据库。测试框架用它来创建临时数据库做单元测试——用完即删,干净利落。

场景四:数据分析与科学计算

处理中等规模的数据集(几 GB 以内),SQLite 比 Pandas 读 CSV 更快、更省内存。你可以用 SQL 直接查询、聚合、JOIN,不用把所有数据加载到内存里。

场景五:原型开发与快速验证

创业公司做 MVP、学生做课程项目、后端开发写 Demo——用 SQLite 可以立刻开始,不用花时间搭建 MySQL。等产品验证成功了再迁移到生产数据库也不迟。

场景六:配置与元数据存储

用 SQLite 替代 JSON / XML 配置文件。好处是可以用 SQL 查询,支持事务(不会写一半崩溃导致配置文件损坏),而且还能建索引加速查找。

一句话概括:凡是需要 「应用本地结构化存储」「不需要多客户端并发写入」 的场景,首选 SQLite。


1.4 SQLite vs MySQL / PostgreSQL —— 什么时候该用 SQLite

很多人会问:SQLite 这么好用,能不能拿来做 Web 项目的主数据库?答案取决于你的场景。

对比维度SQLiteMySQL / PostgreSQL
部署方式嵌入应用内,无需安装服务独立服务器进程,需安装配置
数据存储单个磁盘文件服务器管理的文件系统
并发能力多读单写(WAL 模式下可并发读)高并发读写
数据容量理论 281 TB,实际适合 GB 级轻松应对 TB 级
网络访问不支持远程连接支持网络访问
用户权限无(依赖文件系统权限)完整的用户/角色/权限体系
运维成本几乎为零需要 DBA 或运维知识
适合场景本地应用、嵌入式、原型、小型网站生产环境、多用户 Web 应用

选择原则

问自己三个问题:

1. 需要多台服务器同时写入同一个数据库吗?
   → 是:用 MySQL / PostgreSQL
   → 否:继续看第二个问题

2. 需要支持远程网络连接?
   → 是:用 MySQL / PostgreSQL
   → 否:继续看第三个问题

3. 数据量会超过 10 GB、或并发写入 QPS > 100?
   → 是:用 MySQL / PostgreSQL
   → 否:SQLite 完全够用!

一个有趣的趋势

近年来,SQLite 在 Web 场景中正在"逆袭":

┌─────────────────────────────────────────────────┐
│           SQLite 的 Web 新玩法                    │
│                                                 │
│  Litestream  → 实时复制 SQLite 到 S3,实现容灾   │
│  LiteFS     → 在多节点间同步 SQLite,支持只读副本 │
│  Turso      → 把 SQLite 搬到边缘节点(Edge)     │
│  libSQL     → SQLite 的开源分叉,增强网络能力     │
│                                                 │
│  理念:每个用户一个 SQLite 文件,数据离用户最近    │
└─────────────────────────────────────────────────┘

结论:SQLite 和 MySQL / PostgreSQL 是互补关系,不是替代关系。选择的核心依据是应用架构,而不是数据库性能。


1.5 SQLite 的整体架构概览

在深入学习之前,先建立一个对 SQLite 内部架构的整体认知。SQLite 的架构可以分为四层

┌─────────────────────────────────────────────────────┐
│                    应用程序                           │
│           sqlite3_exec("SELECT ...")                │
└────────────────────┬────────────────────────────────┘
                     │  SQL 语句

┌─────────────────────────────────────────────────────┐
│          ① 编译器层(Compiler)                      │
│                                                     │
│   ┌──────────┐   ┌──────────┐   ┌──────────────┐  │
│   │ 分词器    │──→│ 解析器   │──→│ 代码生成器    │  │
│   │ Tokenizer │   │ Parser   │   │ Code Generator│  │
│   └──────────┘   └──────────┘   └──────────────┘  │
│                                                     │
│   把 SQL 文本 → 解析成语法树 → 生成字节码              │
└────────────────────┬────────────────────────────────┘
                     │  字节码

┌─────────────────────────────────────────────────────┐
│          ② 虚拟机层(Virtual Machine / VDBE)        │
│                                                     │
│   逐条执行字节码指令,类似 Java 的 JVM               │
│   这是 SQLite 的核心执行引擎                         │
└────────────────────┬────────────────────────────────┘
                     │  读/写数据请求

┌─────────────────────────────────────────────────────┐
│          ③ 存储引擎层(B-Tree + Pager)              │
│                                                     │
│   ┌──────────────┐     ┌──────────────────────┐    │
│   │  B-Tree 模块  │────→│  Pager(页面管理器)  │    │
│   │  组织数据结构  │←────│  管理缓存、事务、锁   │    │
│   └──────────────┘     └──────────┬───────────┘    │
│                                    │                 │
│   每个表和索引都是一棵 B-Tree       │                 │
└────────────────────────────────────┼─────────────────┘
                                     │  文件 I/O

┌─────────────────────────────────────────────────────┐
│          ④ OS 接口层(VFS)                          │
│                                                     │
│   Virtual File System —— 抽象文件操作               │
│   不同操作系统用不同的实现(Unix / Windows)          │
│   负责:文件读写、文件锁、内存映射                    │
└────────────────────┬────────────────────────────────┘


              ┌──────────────┐
              │  database.db  │
              └──────────────┘

几个关键概念

页面(Page):SQLite 把数据库文件分割成固定大小的页面(默认 4096 字节)。所有数据的读写都以页面为单位。

数据库文件 = 一连串固定大小的页面

┌────────┬────────┬────────┬────────┬────────┐
│ Page 1 │ Page 2 │ Page 3 │ Page 4 │  ...   │
│ (头页)  │ (数据)  │ (数据) │ (索引)  │        │
└────────┴────────┴────────┴────────┴────────┘

     包含文件头信息(魔数、版本、页面大小等)

B-Tree:每张表的数据和每个索引都组织成一棵 B-Tree。这让 SQLite 可以高效地按主键查找、范围扫描和有序遍历。

WAL(Write-Ahead Logging):写操作先记录到日志文件,再同步到主数据库文件。这是 SQLite 实现事务安全和并发读写的关键机制(后续章节会详细介绍)。

现在只需要记住:SQL 语句从输入到执行,经历了 编译 → 虚拟机执行 → B-Tree 读写 → 文件 I/O 四个阶段。整个过程都发生在你的应用进程内部,没有网络通信。


本章小结

知识点要点
SQLite 本质嵌入式关系型数据库引擎,单文件存储
设计哲学零配置、无服务器、单文件、自包含
核心场景移动端、桌面应用、缓存、数据分析、原型开发
与 MySQL/PG 的关系互补而非替代,核心差异在部署架构而非性能
内部架构编译器 → 虚拟机 → B-Tree/Pager → OS 接口(VFS)
部署量全球超过 1 万亿个活跃部署,最广泛的数据库引擎

下一章预告:动手把 SQLite 跑起来——安装、启动 sqlite3 命令行工具、执行你的第一条 SQL 语句。

坚持是一种品格