数据库 · 后端 · 架构 · 独立开发

先问写入方式:独立开发者的数据库选择

在本地文件、单体服务和多实例写入之间做选择;用访问方式、写入竞争与恢复责任判断 SQLite 或客户端—服务器数据库。

新项目常把数据库选型当作“功能谁更多”的比较,结果是产品还没有真实写入负载,就先承担了高可用、复制和多套运维配置。更有用的问题是:谁在什么位置写数据、写入能否排队、以及故障后由谁恢复。

本文只讨论应用的主数据存储,不把缓存、搜索、分析仓库和消息队列混成一个选择题。复核日期为 2026-09-03;托管服务的套餐、地区和价格变化很快,本文不据此给出推荐。

先画出数据访问图

在选引擎前写下三件事:

  1. 发出 SQL 的应用与数据文件是否在同一台机器或同一受控环境;
  2. 会不会有多个进程或实例同时写同一份业务数据;
  3. 丢失最近一次写入、无法恢复误删,分别会造成什么后果。

如果答案是“单个应用进程写一份本地数据,写入可以短暂等待”,SQLite 是可以认真考虑的起点。SQLite 官方将它定位为本地应用和设备上的嵌入式存储;一个数据库文件同一时刻只有一个写入者,但多个读取者可以并行。这个限制不是容量猜测,而是并发模型:需要许多写入者同时推进、或多个网络节点直接共享数据时,应选择客户端—服务器数据库。SQLite 的选择清单对此给出了适用条件。

反过来,用户通过 HTTP 访问你的应用,并不自动意味着 SQLite 不可用。关键是应用服务器是否在本机持有数据库文件、是否把对文件的并发访问收敛到应用层;不要把同一个 SQLite 文件放在不可靠的网络文件系统上,让多个机器直接读写。

两条起步路径

路径 A:本地数据或单个服务实例

适合离线优先应用、桌面工具、内部脚本,或写入竞争很低的单体服务。需要落实的不是“先上 WAL”,而是三个可验证动作:

  • 设定事务边界,避免把外部 API 调用或长计算放在写事务里;
  • 以应用真实的并发写入场景测试锁等待与失败处理;
  • 把备份和恢复演练写进发布流程。

WAL 是 SQLite 的日志模式选项,它能改善读写并行的某些场景;它不能把单写入者模型变成多写入者模型。是否启用、同步级别如何设置,应以部署文件系统、断电风险和恢复要求测试后决定,细节见 SQLite 的 WAL 文档。

路径 B:多实例共享业务数据

当 Web 或任务工作者需要横向扩展、多个服务要以不同身份访问同一份数据,或写入不能排队时,采用 PostgreSQL、MySQL 等客户端—服务器关系数据库更容易把连接、权限、备份和并发控制放在专门的服务边界。此时也不要因为“未来可能很大”就先做分片;先建立迁移、慢查询观察和恢复程序。

选 PostgreSQL 还是 MySQL,应从既有团队能力、目标环境支持、迁移工具和所需 SQL 特性出发。任何特定 JSON、全文检索或扩展能力,都应以所选版本的官方文档为准,而不是假设两者可无成本替换。

关系模型不是落后的默认值

如果业务需要订单、权限、账单或其他有明确约束的记录,先用关系表、外键和事务表达不变量。文档模型适合字段形态确实随记录变化、且主要按整份文档读取的对象;它不会自动省去索引、访问控制和迁移设计。

缓存也不是主数据的替代品。把可重建的数据放进缓存,给失效、容量上限和未命中路径做测试;不要让“缓存里有数据”成为唯一事实来源。分析查询同样可以另用面向分析的存储,但应与在线交易数据的恢复责任区分开。

从第一天开始设计迁移

选型可变,数据不可随意重来。无论使用哪种引擎,至少保留:

  • 版本化的 schema 变更;
  • 在生产前可重复执行的迁移演练;
  • 对破坏性修改的兼容阶段(先扩展、再迁移、最后收缩);
  • 可还原到隔离环境的备份。

迁移失败时,先确认旧版本是否还能理解新数据。若不能,代码回滚并不等于数据恢复。关于把数据变更拆成可逆阶段,可参阅《发布与回滚:先设计停止条件,再改生产环境》。

选择前的五个问题

问题 倾向
数据主要在一个设备或一个受控应用进程中使用吗? 先评估 SQLite。
多台机器需要直接、同时写同一份数据吗? 选择客户端—服务器数据库。
写入可否短暂排队? 可以时,单写入者模型可能足够;不可以时,先压测并发路径。
是否有人负责补丁、备份、告警和恢复? 没有时优先减少自管组件,或明确补上这些责任。
能否把备份恢复到隔离环境验证? 不能时,先解决恢复,再讨论扩展。

数据库不是一次性承诺。选择一个能被当前团队运维、能被迁移脚本覆盖、并能从备份恢复的起点,比为未经验证的规模预留复杂架构更可靠。

参考资料

延伸阅读