The 1st edition CouchDB book from 2009 or thereabouts explained it like this:
> We write software to improve our lives and the lives of others. Usually this involves taking some mundane information—such as contacts, invoices, or receipts—and manipulating it using a computer application. CouchDB is a great fit for common applications like this because it embraces the natural idea of evolving, self-contained documents as the very core of its data model.
> Self-Contained Data
> An invoice contains all the pertinent information about a single transaction—the seller, the buyer, the date, and a list of the items or services sold. As shown in Figure 1, “Self-contained documents”, there’s no abstract reference on this piece of paper that points to some other piece of paper with the seller’s name and address. Accountants appreciate the simplicity of having everything in one place. And given the choice, programmers appreciate that, too.
> Yet using references is exactly how we model our data in a relational database! Each invoice is stored in a table as a row that refers to other rows in other tables—one row for seller information, one for the buyer, one row for each item billed, and more rows still to describe the item details, manufacturer details, and so on and so forth.
Iow, a document database stands in contrast to a relational db in that these JSON things we store in them are more stand-alone “documents” compared to storing data in rows and columns in a relational db like PostgreSQL or SQLite.
I am using SQLite as document db for a side project for years now. Made a custom repository base class that can also store blobs in separate columns, so this type of data is not part of the json document. Today there is also jsonb [1], as far as I remember all functions work the same for json and jsonb.
Also the repo class stores write and delete timestamps as separate columns so I can have CDC. CDC is used for building cached view models and is pushed to object storage every 5 minutes for backup as NDJSON. Another process on home server is restoring the db every couple of minutes for second backup and ready to use DB in case it's needed.
I know there are things like Litestream, I wanted something in process and something that can send alerts on failed backups.
A long time ago, I wrote an ORM to serialize/deserialize object data seamlessly into SQLite, with massive arrays of floats being stored as blobs.
In code, I could effectively mark which class members need to be stored/restored, and optionally provide a custom serialization function for them if needed.
The latter was effectively never necessary, because all the bases types and multi-dimensional arrays were handled by templates.
Really wish I open-sourced that thing then, but the corporate bureaucracy around that was tricky.
I remember sufficiently little about implementation details now that I think I can get to writing it again, without producing a copypasta of that code - and maybe I should :)
That was the part I really missed from my Google days.
That, insane achievement badges, and terrible-ideas-discuss (if anyone at Google is reading this, I have one word for you: dirigibles). It was like /r/NonCredibleDefense but for Google.
> (Aside: The hard bit may be getting a new enough SQLite, at the time of writing Homebrew on macOS has it, else you likely need to use an unstable source like nixpkgs-unstable.)
> We write software to improve our lives and the lives of others. Usually this involves taking some mundane information—such as contacts, invoices, or receipts—and manipulating it using a computer application. CouchDB is a great fit for common applications like this because it embraces the natural idea of evolving, self-contained documents as the very core of its data model.
> Self-Contained Data
> An invoice contains all the pertinent information about a single transaction—the seller, the buyer, the date, and a list of the items or services sold. As shown in Figure 1, “Self-contained documents”, there’s no abstract reference on this piece of paper that points to some other piece of paper with the seller’s name and address. Accountants appreciate the simplicity of having everything in one place. And given the choice, programmers appreciate that, too.
> Yet using references is exactly how we model our data in a relational database! Each invoice is stored in a table as a row that refers to other rows in other tables—one row for seller information, one for the buyer, one row for each item billed, and more rows still to describe the item details, manufacturer details, and so on and so forth.
https://guide.couchdb.org/editions/1/en/why.html
Iow, a document database stands in contrast to a relational db in that these JSON things we store in them are more stand-alone “documents” compared to storing data in rows and columns in a relational db like PostgreSQL or SQLite.
Also the repo class stores write and delete timestamps as separate columns so I can have CDC. CDC is used for building cached view models and is pushed to object storage every 5 minutes for backup as NDJSON. Another process on home server is restoring the db every couple of minutes for second backup and ready to use DB in case it's needed.
I know there are things like Litestream, I wanted something in process and something that can send alerts on failed backups.
[1] https://sqlite.org/jsonb.html
https://sqlite-tutorial-pycon-2023.readthedocs.io/en/latest/...
https://simonwillison.net/2021/Jul/28/baked-data/
In code, I could effectively mark which class members need to be stored/restored, and optionally provide a custom serialization function for them if needed.
The latter was effectively never necessary, because all the bases types and multi-dimensional arrays were handled by templates.
Really wish I open-sourced that thing then, but the corporate bureaucracy around that was tricky.
I remember sufficiently little about implementation details now that I think I can get to writing it again, without producing a copypasta of that code - and maybe I should :)
https://youtu.be/b2F-DItXtZs?is=HlayyJ_DPb8NzbS4
(lol! couldn’t resist)
That was the part I really missed from my Google days.
That, insane achievement badges, and terrible-ideas-discuss (if anyone at Google is reading this, I have one word for you: dirigibles). It was like /r/NonCredibleDefense but for Google.
So I can have cassette.propxyz = {1, 2, “abc”, true}
And
local anotherprop = cassette.leprop
Or just download the source and build it! (Gasp!)