Quickstart: your first versioned table
Build a tiny document store with pg-xpatch, from an empty table to seeing the deltas on disk, in six short steps.
Quickstart: your first versioned table
This walks you through a tiny document store, from an empty table to seeing the compressed deltas on disk. It assumes pg-xpatch is installed. Every snippet is plain SQL you can paste into psql.
1. Create the table
CREATE TABLE documents ( doc_id INT, version INT, content TEXT NOT NULL) USING xpatch;The USING xpatch clause is the whole trick. Text, bytea, and json columns get delta-compressed; everything else is stored as usual. One rule to remember: delta columns must be NOT NULL, which is why content is.
xpatch adds an internal _xp_seq column for its own bookkeeping. It shows up in SELECT * because PostgreSQL has no hidden columns, so we list columns explicitly below to keep it out of the way.
2. Tell it how to group and order
SELECT xpatch.configure('documents', group_by => 'doc_id', order_by => 'version');group_by makes each doc_id its own independent version chain. order_by is the order of versions inside a chain. configure() also builds a (doc_id, _xp_seq) index for fast lookups.
Auto-detection can guess order_by (the last integer column) and the delta columns, but it cannot guess that you meant to group by document. Set group_by whenever one table holds many independent histories. Configuring a table covers the rest.
3. Insert some versions
Insert versions in ascending version order within each document:
INSERT INTO documents VALUES (1, 1, 'The quick brown fox.'), (1, 2, 'The quick brown fox jumps.'), (1, 3, 'The quick brown fox jumps over the lazy dog.');Each row picks up the next _xp_seq for its group automatically: 1, then 2, then 3. Version 1 is stored in full; versions 2 and 3 keep only what changed.
Insert versions in ascending order_by order within a group. Out-of-order inserts are not rejected, but they compress poorly. And there is no UPDATE: to change a value, insert the next version.
4. Read it back
SELECT works normally. The deltas are reconstructed for you on the fly:
SELECT doc_id, version, contentFROM documentsWHERE doc_id = 1ORDER BY version;All three versions come back in full text. Listing the columns instead of SELECT * keeps the internal _xp_seq out of your result.
5. Check the compression
SELECT total_rows, keyframe_count, delta_count, raw_size_bytes, compressed_size_bytes, compression_ratioFROM xpatch.stats('documents');You will see one keyframe (version 1), two deltas, and compressed_size_bytes already below raw_size_bytes. That gap widens fast as you add more similar versions. xpatch.stats() reads from a stats table that pg-xpatch maintains on every write, so it stays instant even on huge tables.
6. Peek at what is on disk
This is the part that makes it click. xpatch.inspect() shows how each version is actually stored:
SELECT version, is_keyframe, tag, delta_size_bytesFROM xpatch.inspect('documents', 1); -- 1 is the doc_idVersion 1 is the keyframe. Versions 2 and 3 are deltas whose tag = 1 means "rebuild me from the row one back," and their delta_size_bytes is a fraction of the keyframe's.
| version | is_keyframe | tag | stored as |
|---|---|---|---|
| 1 | true |
0 | the full text (a keyframe) |
| 2 | false |
1 | the diff against version 1 |
| 3 | false |
1 | the diff against version 2 |
That is the whole loop
You created a table USING xpatch, configured grouping, inserted versions, read them back in full, and watched them get stored as deltas. Nothing about your SQL had to change.
Keyframes, deltas, and reconstruction in depth.
Every configure() option, and when to reach for it.
Warm the cache before heavy reads.
Hat das auf deinem Setup funktioniert?
Noch nicht bewertet