One of my favorite database design patterns is what I call the “mullet schema”: business up front, party in the back, where every table in the database ends with a JSON column.
I even mentioned it on a recent episode of the Talk Python podcast:
This morning, I read David Crawshaw’s excellent post, How I Program With Agents. In a sidebar, he completely blew my mullet-addled mind:
I learned an odd way of using SQL at Tailscale (from Brad and Maisem): make every table a JSON object. In particular, have only one “real” column and the rest generated from the JSON. So the typical table looks like:
CREATE TABLE IF NOT EXISTS Cookie (
Cookie TEXT NOT NULL AS (Data->>'cookie') STORED UNIQUE, -- PK
UserID INTEGER NOT NULL AS (Data->>'user_id') STORED REFERENCES User (UserID),
Created INTEGER NOT NULL AS (unixepoch(Data->>'created')) STORED,
LastUsed INTEGER AS (unixepoch(Data->>'last_used')) CHECK (LastUsed>0),
Data JSONB NOT NULL
);
Now it’s a party!
David mentions some of the tradeoffs and hints at a potential future blog post about the approach. In the meantime, I may need to rethink my mullet nomenclature!