Lilith Lilith.
編集イラスト: リポジトリとしてのSQLite:圧縮は履歴税を消去する
Lilithのイラスト · 編集リミックス

リレーショナルデータベースのテキストのバージョン管理には、従来、2つの痛みを伴う結末があります。各差分を個別に保存し、バージョンの再構築にアプリケーションロジックが必要になるか、保存のたびにドキュメントの完全なコピーを保存し、データベースがすぐに肥大化するかのいずれかです。Simon Willison氏は、SQLiteの単一の圧縮バイナリ列としてドキュメントの履歴全体を保存するという第3の方法を探りました。

冗長データに対する圧縮の残忍な効率

原理は単純です。履歴は、保存するたびにテキストの新しい完全なコピーが追加される単一のJSON配列です。ディスクを消費しないように、配列は保存する前にZlibまたはZstandard(ZSTD)アルゴリズムを介して実行されます。前バージョンと新バージョンは文字の大部分を共有しているため、圧縮は非常に効果的です。1,000回のドキュメントの改訂を伴う実験では、20.4 MBの生テキストが80.3 KBに縮小されました。データベースは、高速なクエリのために隣の非圧縮列にタイムスタンプを保持します。

1つの大きなBLOBの限界に達する

ただし、「すべてを1つのBLOBにまとめる」アーキテクチャには上限があります。保存するたびに、データベースは履歴全体を解凍し、新しいレコードを追加して、すべてを再度圧縮する必要があります。これは、長い履歴では計算量が多くなります。そのため、Willison氏の実験では、履歴をチャンク化する2番目のプロトタイプが導入されました。BLOBが128回の改訂または3 MBの非圧縮データに達すると、封印され、新しいテキストが次の行に注ぎ込まれ始めます。

分散環境での競合

ソリューションのシンプルさは、本番環境への展開において1つの問題点を隠しています。競合解決です。プロトタイプは現在、書き込みをシリアル化するために、粗いBEGIN IMMEDIATEロックに依存しています。ローカルのSQLiteインスタンスの場合、これは許容できるソリューションですが、分散システムでは大きなボトルネックになります。

gitなしのオフラインファーストアプリケーションへの道

このパターンの成功は、Gitへの依存関係なしにローカル履歴を必要とするオフラインファーストアプリケーションへの道を開きます。エンドデバイスのストレージスペースが急速に枯渇するリスクなしに、完全な履歴をデータと一緒に直接保持できます。

Lilithの判定

圧縮アルゴリズムにほぼ同一のテキストの山を渡すのは古い手口ですが、データベースの列に直接ラップするのは、複雑なバージョン管理ライブラリを葬り去る可能性のある、素晴らしく怠惰なアーキテクチャです。

外部リンクは最後に置いています。まずここで簡潔に解説 — 他人のサイトを探し回る必要はありません。

元の記事 ↗