Simon Willison 探索在 SQLite 中高效存储文档版本历史的新方法:将所有历史版本放入 JSON 数组再用 zstd 压缩,实验显示压缩效果极佳。
我一直对在关系型数据库中存储修订历史的各种方案很感兴趣。有一天在遛狗的时候我冒出了一个新想法:把每个历史版本的完整文本放进一个大的 JSON 字符串数组,然后对整个数组应用 zlib 或 zstd 压缩——由于存在大量重复字符串,这样应该能获得非常好的压缩效果。
ChatGPT iPhone 应用的新 GPT‑Live 语音模式效果已经相当不错了,所以我用它来讨论这个原型。你仍然无法分享语音对话的链接,但以下内容是从转录文本中复制出来的原始思维流:
我有一个很有趣的想法,关于如何在 SQLite 数据库的某个字段中以尽可能高效的方式保存一个不断被编辑的文档的所有历史版本。我以前构建过这类系统,总是很找到高效的解决方案。最简单的办法是每保存一个版本就新增一行记录——但如果是一份 20KB 的长文档,每次编辑都会往数据库里添加 20KB 的数据。所以我现在的想法是,压缩应该能很好地解决这个问题——如果你把所有历史版本从头到尾全部打包在一起,然后应用一个好的压缩算法,应该能基本上消除大量的冗余文本。所以我在想,能不能有一个超级简单的机制:在某张表上增加一个历史记录列,它是一个 blob,用来存储二进制数据,然后在里面塞一个用 zlib 或甚至 zstd 压缩的 JSON 文本数组,包含所有历史文档。所以你大概需要两个列,对吧?一个列是这个魔法的 JSON 文本数组,还有一个第二列是时间戳的 JSON 数组——而这个完全不需要压缩,对吧?时间戳可以只是一个整数数组,Unix 时间戳整数。但这就是整个方案。
然后我停止了语音模式,向 GPT-5.6 Sol Pro 输入了以下文本提示:
Use Python and Build experimental prototypes around this idea
它跑了 38 分钟,然后交付了这个答案以及你在这个文件夹里看到的文件。
这个方案效果非常好!对一份文档模拟 1000 次修订,原始修订文本为 20.4 MB,作为 Zstandard 压缩的 JSON 数组压缩后仅为 80.3 KB。
为了避免每次编辑时解压和重新压缩整个数组的巨大开销,Sol 建议将历史记录拆分成多行,每行最多包含 128 次修订或 3MB 未压缩的 JSON。
现在我们有了时间线:
OpenAI 意外攻击 Hugging Face 的始末 — 2026 年 8 月 7 日
用 Claude Fable 5 一击通关 Raccoon Heist 游戏 — 2026 年 8 月 5 日
新版 LLM 支持推理追踪、OpenAI Responses、服务端工具和更智能的日志记录 — 2026 年 8 月 4 日
这是 Simon Willison 的报道,发布于 2026 年 8 月 9 日。
每月赞助 $10,即可获得当月最重要 LLM 进展的精选邮件摘要。
付费让我给你发得更少!