Simon Willison · 博客

SQLite压缩文本历史原型

SQLite compressed text-history prototypes

二〇二六年八月九日 · 英文原文

一项针对SQLite中存储文本修订历史的压缩方案原型研究。方法是将所有旧版本全文存入JSON字符串数组,整体应用zlib或zstd压缩,并配合Unix时间戳数组。实验使用GPT-5.6 Sol Pro构建Python原型,对文档进行1,000次模拟修订,原始文本20.4 MB经Zstandard压缩后降至80.3 KB。为避免每次编辑的解压重压缩开销,历史被拆分为多行,每行最多128个修订或3 MB未压缩JSON。

研究:SQLite 压缩文本历史原型

我一直对在关系数据库中存储修订历史的各种方案感兴趣。遛狗时我冒出一个新想法:把每个旧版本的全文放进一个大的 JSON 字符串数组,然后对整个数组应用 zlib 或 zstd 压缩,会怎样?由于存在大量重复字符串,压缩效果应该会非常好。ChatGPT iPhone 应用里新的 GPT-Live 语音模式已经相当出色,于是我和它讨论了这一原型。目前仍无法分享语音对话的 URL,但以下是我从转录中复制出来的原话,算是一段意识流:

我有一个有趣的想法,关于如何尽可能高效地在 SQLite 数据库的列中保存一段不断编辑的文本的所有历史版本。过去我构建过这类系统,要找到高效方案总是很难。最简单的方式是为每个旧版本字符串单独建一行。但如果文档很长,比如 20 千字节,那么每次编辑都会往数据库里增加 20 千字节的数据,对吧。所以,我现在想的是,压缩应该会很有效,对吧?如果你把从最初到现在的所有版本打包在一起,再应用一个好的压缩算法,基本上就能消除大量冗余文本。所以我的想法是,用一个非常非常简单的机制:表上有一个历史列,它是 BLOB 类型,存储二进制数据,然后你只需把压缩过的 JSON 文本数组(包含所有旧文档)放进去。这样你大概需要两列,对吧?一列是那个神奇的 JSON 文本数组,另一列是 JSON 时间戳数组,后者根本不需要压缩,对吧?时间戳就是整数数组,Unix 整数。整个方案就是这样。

然后我退出语音模式,向 GPT-5.6 Sol Pro 输入了以下文本提示:

用 Python 围绕这个想法构建实验原型。

它运行了 38 分钟,给出了以下答案以及你在此文件夹中看到的文件。这个方法效果非常好!对文档进行 1,000 次模拟修订,原始修订文本共 20.4 MB,压缩为 Zstandard 压缩的 JSON 数组后仅 80.3 KB。为了避免每次编辑时解压并重新压缩整个数组的开销,Sol 建议将历史拆分为多行,每行最多包含 128 个修订或 3 MB 未压缩 JSON。

标签:压缩、SQLite、语音转文本

译自 Simon Willison · 博客 · 录于 二〇二六年八月九日