你曾经忽视的数据库值得重新审视
多年来,建议很简单:SQLite 用于原型、移动应用和测试套件。如果你在构建任何”真实”的东西,你需要 PostgreSQL、MySQL,或者至少需要一个每月账单会让你的会计师皱眉的托管数据库服务。这个建议在 2015 年是合理的。但在 2026 年,它越来越错误。
SQLite 生产环境用例已经显著扩展,这得益于新工具的融合、向更简单架构的理念转变,以及大多数应用程序不需要分布式数据库集群的经济现实。这个随操作系统一起提供、需要零配置、并将所有内容存储在单个文件中的数据库,已经成为生产工作量的有力竞争者,这在几年前是难以想象的。
这不是为了争议而提出的相反观点。这是对 SQLite 适用场景、不适用场景以及为什么这两个区域之间的界限已经显著转移的实际评估。
SQLite 的复兴:发生了什么变化
SQLite 本身几十年来就已经是生产级别的。它驱动着每一部 iPhone、每一台 Android 设备、每一次 Firefox 和 Chrome 安装。这个引擎每天处理的查询量比所有其他数据库引擎加起来还要多。变化的不是 SQLite 的可靠性,而是它周围的生态系统。
Litestream:无需复杂性的持续复制
Ben Johnson 的 Litestream 解决了 SQLite 最关键的生产环境缺口:备份和灾难恢复。Litestream 通过近乎实时地流式传输 WAL(预写日志)更改,将 SQLite 数据库持续复制到与 S3 兼容的存储中。恢复点目标从几小时缩短到几秒钟。没有 cron 作业,没有 pg_dump 等价物,没有备份间隔之间可能丢失数据的窗口。
操作上的简单性令人印象深刻。你在应用程序旁边运行一个单一的 sidecar 进程。它监视 WAL 文件并将更改发送到对象存储。恢复涉及下载基础快照并重放 WAL 帧。整个备份基础设施是一个二进制文件和一个存储桶策略。
LiteFS:边缘的分布式 SQLite
Fly.io 的 LiteFS 采用了不同的方法,使用基于 FUSE 的文件系统在多个节点间复制 SQLite 数据库。一个主节点处理写入操作,副本通过轻量级共识机制接收更改。这实现了跨地理区域的读取扩展,同时保持了 SQLite 的单文件简单性。
LiteFS 做了一个特定的赌注:大多数 Web 应用程序都是读密集型的,在东京、伦敦和圣保罗用户附近放置读取副本,所带来的延迟改进是任何连接到集中式 Postgres 实例的连接池都无法比拟的。
Turso 和 libSQL:SQLite 获得了网络协议
Turso 将 SQLite 分叉为 libSQL,并添加了服务器端开发人员多年来一直要求的功能:用于远程访问的网络协议、原生复制原语,以及允许用户定义函数而无需重新编译的扩展。libSQL 保持与 SQLite 文件格式的完全兼容性,同时打开了使用先前需要客户端-服务器数据库的使用模式。
这里的意义在于架构。您可以在应用程序中嵌入运行 libSQL 以获得本地性能,同时通过 HTTP 暴露它,以便用于工具、仪表板和管理访问。
WAL 模式和并发:理解真正的限制
关于 SQLite 最持久的误解是它无法处理并发访问。在默认日志模式下,这在某种程度上是正确的。在 WAL 模式下(这应该是每个生产 SQLite 部署的默认设置),情况发生了显著变化。
WAL 模式允许多个并发读取者和单个写入者。读取者永远不会阻塞写入者,写入者也永远不会阻塞读取者。读取事务会看到数据库的一致性快照,无论是否有写入正在进行。对于绝大多数 Web 应用程序(其中读取与写入的比例为 10:1 或更高),这种并发模型是完全足够的。
真正的限制是序列化写入。SQLite 一次处理一个写入事务。在现代 NVMe 存储上,单个 SQLite 写入者可以每秒维持数万个写入事务。瓶颈不是原始吞吐量,而是长时间运行的写入事务,它们持有锁并导致其他写入者饥饿。
实际规则:如果您的写入工作负载适合单台机器,并且您的写入事务很短,那么 SQLite 的并发模型不会成为限制您的东西。
生产 WAL 模式部署的关键 pragmas:
PRAGMA journal_mode=WAL;
PRAGMA busy_timeout=5000;
PRAGMA synchronous=NORMAL;
PRAGMA cache_size=-64000;
PRAGMA foreign_keys=ON;
PRAGMA temp_store=MEMORY;
busy_timeout pragma 是至关重要的。没有它,并发写入尝试会立即返回 SQLITE_BUSY 而不是重试。五秒的超时处理几乎所有的瞬时争用,而无需应用级别的重试逻辑。
何时 SQLite 优于 PostgreSQL
这并不是说 SQLite 在所有方面都更好。而是要确定 SQLite 架构真正提供优势的具体条件。
读密集型单服务器应用。当您的整个数据集可以放入内存(或快速本地 NVMe)中,并且您的应用程序运行在一台机器上时,SQLite 消除了到数据库服务器的网络往返。每个查询都是本地函数调用。延迟从毫秒级降至微秒级。对于一个发出五到十个数据库查询的典型网页请求,这可以转化为尾部延迟的可测量改善。
嵌入式分析和内部工具。为少量并发用户提供服务的仪表板、管理面板和报告工具是 SQLite 理想的生产用例。为一个五人团队使用的工具运行专用的 Postgres 实例,其运营成本难以证明其合理性。
边缘部署。通过 Fly.io 或 Cloudflare 等平台部署到多个地理区域的应用程序,从与应用程序位于同一台机器上的数据库中获益匪浅。每次读取都是本地操作。写入传播通过 Litestream 或 LiteFS 异步完成。
数据量可预测的应用程序。如果您的应用程序将处理已知、有限的数据量,比如每个租户最多生成几 GB 数据的 SaaS 工具,那么 SQLite 的扩展上限就无关紧要,因为您永远不会达到它。
SQLite 与 PostgreSQL:工作负载比较
| 工作负载类型 | SQLite | PostgreSQL | 结论 |
|---|---|---|---|
| 单服务器Web应用(<1000 RPS) | 优秀;零延迟读取 | 良好;增加网络开销 | SQLite |
| 写入密集型事务(如支付) | 序列化写入;有限制 | MVCC支持并发写入 | PostgreSQL |
| 多服务器水平扩展 | 需要LiteFS或Turso | 原生复制,成熟工具 | PostgreSQL |
| 边缘/区域部署 | 本地读取,快速复制 | 需要只读副本+延迟 | SQLite |
| 嵌入式分析&内部工具 | 零运维,即时设置 | 对小团队来说过于复杂 | SQLite |
| 复杂查询(CTE、窗口函数) | 3.25+版本支持 | 全功能查询规划器 | PostgreSQL(略胜) |
| 全文搜索 | 内置FTS5,功能完善 | 与tsvector/GIN配合出色 | 平局 |
| JSON工作负载 | 3.38版本支持JSON函数 | JSONB支持索引 | PostgreSQL |
| 每租户一个数据库(多租户SaaS) | 每个文件提供简单隔离 | 模式级或连接级隔离 | SQLite |
| CI/CD和测试 | 内存模式,即时,可丢弃 | 需要容器或服务 | SQLite |
实际生产用例
Rails与Solid Queue和Solid Cache
Rails 8的发布使SQLite成为一流的生产数据库。Solid Queue作为默认的Active Job后端,将作业状态存储在数据库本身,而不是需要Redis。Solid Cache对缓存做同样的事情。Rails 8应用程序可以在单个SQLite数据库上运行其Web服务器、后台作业和缓存层,无需任何外部依赖。
这不是一个玩具配置。Rails团队特别针对生产工作负载优化了SQLite适配器,添加了自动WAL模式、连接池改进以及对繁忙状态的重试逻辑。DHH在测试期间已公开使用此堆栈运行过Basecamp规模的应用程序。
Fly.io模式:每用户一个数据库
SQLite最引人注目的生产用例之一是在Fly.io上的每租户一个数据库模式。每个用户或租户都有自己的SQLite文件,通过LiteFS进行复制。这提供了完全的数据隔离(不会意外发生跨租户查询),简单的每租户备份和恢复功能,以及将每个租户的数据放置在其首选地理区域的能力。
这种模式也简化了合规性。当客户根据 GDPR 请求删除数据时,你只需删除一个文件。无需在共享表上进行精确的 DELETE 查询,无需担心孤立的外键引用,也无需审计跟踪中是否捕获了每一行的疑虑。
嵌入式分析和可观测性
多种可观测性工具,包括 Grafana Loki 的本地存储模式和各种日志聚合系统,都使用 SQLite 作为其单节点部署的存储后端。其性能特点十分有利:顺序写入速度快,通过适当索引对时间序列数据进行范围扫描效率很高,整个数据库可以复制或传输到另一台机器进行分析,无需任何导出过程。
重要的性能特点
SQLite 的原始基准测试数字常常具有误导性,因为它们省略了任何客户端-服务器数据库必然引入的网络延迟。有意义的比较是端到端请求延迟,在这方面,SQLite 在单服务器部署中具有结构性优势。
在现代配备 NVMe 存储的 VPS 上的典型数据:
- 按主键进行简单 SELECT: 5-15 微秒(SQLite)vs. 200-500 微秒(通过本地套接字的 PostgreSQL)
- 使用 WAL 模式的 INSERT: 每行 20-50 微秒
- 事务中的批量 INSERT: 每秒 50,000-100,000 行,具体取决于行大小和索引数量
- 数据库大小的实际上限: 100-200 GB,在此之前你不会注意到操作摩擦(备份时间、VACUUM 持续时间)
微秒与毫秒的差异看似学术,但它会累积。一个发出 20 个查询的网页请求在每个请求上节省 4-10 毫秒。在规模上,这就是舒适余量与性能焦虑之间的区别。
生产 SQLite 的备份策略
没有备份策略的生产 SQLite 部署是疏忽。好消息是,可用的选项简单可靠。
- Litestream 到 S3: 具有亚秒级 RPO 的持续 WAL 流式传输。这应该是每个生产部署的基线。成本可以忽略不计,因为 WAL 帧很小,而 S3 的定价是以每 GB 几美分计算的。
- 定期快照: 使用
.backup命令或 SQLite 在线备份 API 创建一致的时点快照。将这些操作安排为每小时或每天执行,作为第二层备份。 - 卷快照: 如果您的 VPS 提供商支持块级快照(大多数都支持),这些快照会提供整个磁盘的崩溃一致性备份,包括 SQLite 数据库。恢复涉及从快照启动新实例。
- 跨区域复制: 配置 Litestream 将数据复制到多个区域的存储桶中。这提供了地理冗余,而无需任何额外的应用程序复杂性。
不要在活动的 SQLite 数据库上使用 cp 或 rsync。文件可能在事务中途处于不一致状态。始终使用备份 API、Litestream 或保证原子捕获的文件系统快照。
单服务器的最佳选择
有一种特定的架构配置非常适合 SQLite,而且比业界承认的更为常见:单服务器应用程序。配置良好的 VPS,拥有 8 个核心、32GB RAM 和 NVMe 存储,可以处理相当大的流量。许多产生可观收入的 SaaS 应用程序、拥有数千日活跃用户和数百万月请求的产品,都能在这种硬件上舒适地运行。
业界默认假设每个应用程序从一开始就需要水平扩展,这导致了巨大的意外复杂性。连接池、只读副本、缓存失效层和分布式事务协调器都是针对单服务器 SQLite 架构根本不存在的问题的解决方案。
经济上的论点同样令人信服。一台 Hetzner 或 OVH 的专用服务器每月费用为 50-100 美元。而主要云提供商提供的性能相当的托管 PostgreSQL 实例起价为每月 200-500 美元。对于初创产品和独立开发者来说,这个差异可以支撑数个月的运营。
迁移路径:当您超出 SQLite 的能力范围时
负责任地倡导 SQLite 需要诚实地讨论其局限性。当以下情况发生时,您将需要迁移:
- 您的写入吞吐量需要多台机器上的并发写入者
- 您的数据集增长到无法舒适地适应单台服务器存储的程度
- 您需要高级 PostgreSQL 功能,如 LISTEN/NOTIFY、逻辑复制或专用扩展(PostGIS、pgvector)
- 您的团队变得足够大,需要多个服务通过网络独立访问数据库
迁移路径是成熟的。SQLite 的 SQL 方言与 PostgreSQL 足够接近,大多数查询只需少量修改即可转移。主要摩擦点在于数据类型差异(SQLite 的类型亲和系统与 PostgreSQL 的严格类型)、自增语法(AUTOINCREMENT 与 SERIAL/GENERATED)以及日期时间处理。ActiveRecord、Prisma 和 SQLAlchemy 等 ORM 抽象了这些差异的大部分,使迁移主要成为部署问题而非代码重写。
关键见解:从 SQLite 开始并不会让你陷入困境。它在产品阶段为您带来简化,而简化正是最重要的,同时为当复杂性变得合理时提供了清晰的升级路径。
常见误解,已辟谣
“SQLite 不支持并发访问。” WAL 模式支持无限并发读取者和一个写入者。对于读密集型 Web 工作负载,这很少成为瓶颈。
“SQLite 只适用于小型数据集。” 最大数据库大小为 281 太字节。实际操作限制在数百 GB,这涵盖了大量生产应用。
“SQLite 不符合 ACID 标准。” SQLite 完全符合 ACID 标准。自创建之初就一直如此。它通过了比大多数客户端-服务器数据库更多的合规测试。
“你不能在 Docker 中使用 SQLite。” 你可以使用,但需要注意数据库文件必须位于持久卷上,而不是在容器的临时文件系统中。这与 Docker 中任何有状态数据的约束相同。
“SQLite 没有查询规划器。” SQLite 有一个复杂的查询规划器,可以处理 JOIN、子查询、CTE、窗口函数和部分索引。对于复杂分析查询,它可能无法匹配 PostgreSQL 的规划器,但它比大多数开发者想象的要强大得多。
诚实评估
SQLite 的生产用例有明确的边界。如果您正在构建单服务器应用、边缘部署服务、嵌入式系统,或者运营简化是竞争优势的产品,那么 SQLite 不是妥协,而是正确的技术选择。
数据库世界花了二十年时间优化那些 99% 的应用永远无法达到规模的公司需求。这样做,它为那些只需要一个可靠的数据存储和查询位置的开发者引入了大量不必要的复杂性。SQLite 及其现代生态系统(Litestream、LiteFS 和 libSQL)为这些工作负载提供了一种回归理性的选择。
最简单的数据库有时就是正确的选择。比行业愿意承认的更常见。
