SQLite 文本修订历史的压缩存储实验
Simon Willison2026-08-11 05:03
问题:文本修订历史为何占空间
在关系型数据库中保存持续编辑文本的历史版本,最直接的做法是每次修改都存储一份完整文本。但对于约 20KB 的长文档,每次编辑都可能额外占用约 20KB,长期累积后存储成本较高。
实验方案:将完整历史整体压缩
该实验提出了一种较简单的实现方式:
- 在 SQLite 表中使用 BLOB 字段保存历史内容;
- 将每个历史版本的完整文本组成 JSON 字符串数组;
- 对整个 JSON 数组使用 zlib 或 Zstandard 压缩;
- 时间戳则单独保存为 Unix 时间戳数组,未必需要压缩。
其核心假设是:相邻修订版本通常存在大量重复文本,因此把所有版本放在一起压缩,能够利用跨版本重复内容获得较高压缩率。
实验结果
在一次包含 1000 次模拟修订的测试中:
- 原始修订文本总量:20.4MB
- Zstandard 压缩后的 JSON 历史数组:80.3KB
这说明,对于内容变化相对有限、版本之间重复度较高的文档,整体压缩完整历史可能显著减少存储体积。
实现上的取舍:避免每次编辑都重压全部历史
整体压缩也带来写入成本:每次新增修订都要解压现有历史、追加新版本,再重新压缩全部内容。
为减少这一开销,实验建议将历史拆分为多行分段保存。每个分段最多包含以下任一上限:
- 128 个修订版本;
- 3MB 未压缩 JSON 数据。
新增版本时通常只需处理最新分段,而不必反复解压和重压整个文档的完整历史。
适用场景与注意点
这种方案适合保留完整版本、且相邻版本高度相似的文本型数据,例如文档草稿、配置内容或持续编辑的记录。实际采用前仍需评估:
- 读取单个历史版本时的解压和 JSON 解析成本;
- 历史分段大小对读写延迟的影响;
- 删除、检索和并发更新历史记录时的实现复杂度;
- 文本变化幅度较大时,压缩率是否仍能保持优势。