5 ms·
SQLite as a Document Database (2020)
- stanac 1mo agoI 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. [1] https://sqlite.org/jsonb.html https://sqlite.org/jsonb.html
- kreelman 1mo agoIf I create a view of a table containing JSON data (or any other kind of data), I can create columns from calculations on existing fields. I'm guessing the advantage of generated columns is that they are real columns, not computed columns like in a view. This means that if an insert doesn't work with the new generated column an error will be generated? Is that a correct understanding ? Is this perhaps the main advantage of this feature ? The data creation and storage options, always computed or stored on write of dependant columns seems like a possible advantage too.
- artyomsv 1mo agoMain practical difference is that you can put index on generated column, and on view you cannot, SQLite has no materialized views. Constraint part you understood right, NOT NULL on generated column fails at insert, and note that VIRTUAL costs nothing on disk but can still be indexed, so STORED is mostly for when expression itself is expensive.
- mococa 1mo agoIn my personal project (a game) I use an indexed key + a JSONB to store the save state, which comes from Lua. So I can have cassette.propxyz = {1, 2, “abc”, true} And local anotherprop = cassette.leprop
- nonethewiser 1mo agoAre you doing this because you also use SQLite for other relational data?
- mococa 1mo agoPossibly yes, otherwise I could use another simple solution
- smalltorch 1mo agoIs this new or something? Works amazing as a document backend.
- eventualcomp 1mo agoAlmost 6 years old. (2020).
- antonvs 1mo ago> (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.) Or just download the source and build it! (Gasp!)
- Groxx 1mo agoEven easier: click the download link on the website. https://sqlite.org/download.html https://sqlite.org/download.html
- bbkane 1mo agoThe great thing about using a package manager is that it also handles updating and uninstalling software, not just the initial install
- antonvs 1mo agoSure, but the point is (1) that you don’t need a package manager to install software, which the comment I replied to seemed to assume, and (2) that for something you’re developing against like SQLite, installing it via package manager really isn’t that important. It doesn’t need to integrate with the rest of your system the way typical apps might. What seems to be happening here is that people have learned that package managers are the right way to install software, but they don’t really understand the reasons, or where and how exceptions might apply. IMO your comment does that as well.
- bbkane 1mo agoEven for a personal project such as the one in the blog post, I'd still rather use a package manager to install SQLite. It's POSSIBLE to build it from source, and manually re-download the source and C compiler (and any dependencies, though I'm not sure SQLite has any) when I want to update and instruct any collaborators to do the same thing... But I'd still rather automate it all with a package manager. Especially because I'm probably also handling other dependencies in the project and I value the uniform simplicity of using a package manager for all of them
- tolerance 1mo agoIs this not similar to what Simon Willison has written about before? https://sqlite-tutorial-pycon-2023.readthedocs.io/en/latest/baked-data.html https://sqlite-tutorial-pycon-2023.readthedocs.io/en/latest/... https://simonwillison.net/2021/Jul/28/baked-data/ https://simonwillison.net/2021/Jul/28/baked-data/
- simlevesque 1mo agoCheck the dates, the "before" part is inaccurate.
- tolerance 1mo agoI'm sorry, I didn't mean before 'this'. I shouldn't have even said "before". That was me thinking to myself out loud. What I'm trying to figure out is if they're related concepts. This may be a very naive question awkwardly asked.
- mayankbpatel 1mo agoWhy don’t you use MongoDB? MongoDB is web scale. https://youtu.be/b2F-DItXtZs?is=HlayyJ_DPb8NzbS4 https://youtu.be/b2F-DItXtZs?is=HlayyJ_DPb8NzbS4 (lol! couldn’t resist)
- alterom 1mo agoWait, are all of those shared online? 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.
- nchmy 1mo agowhy is this downvoted...?
- Velocifyer 1mo agoPlease remove everything starting from `is` or `si` from youtube links. The stuff after it is just for tracking.
- WhitneyLand 1mo agoWhy do people say document database when they really just mean json database?
- petcat 1mo agoJSON is just a textual representation of the internal data structures.
- quietbritishjim 1mo agoThat is still not what I'd call a "document".
- QuantumNomad_ 1mo agoThe 1st edition CouchDB book from 2010 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. https://guide.couchdb.org/editions/1/en/why.html 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.
- 1mo ago
- alterom 1mo agoA 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 :)
- inigyou 1mo agoDid it end up becoming more painful than just writing the SQL?
- Hendrikto 1mo agoIt almost always does. People put so much effort into building layers of abstractions to avoid using SQL, while just writing it directly would be much faster, easier, more readable, easier to maintain, modify, and debug. I do not get it.
- alterom 28d ago>It almost always does. People put so much effort into building layers of abstractions to avoid using SQL, while just writing it directly would be much faster, easier, more readable, easier to maintain, modify, and debug. I do not get it. When your data is literally hierarchical and all you need to do is read/write one Big Object, "just using SQL" makes no sense. I used SQLite because it makes a lot of sense to use as an application file format[1], i.e. as an alternative to writing directly to the filesystem. The hierarchical data was a mix of parameters and huge blobs, so text-based JSON was a no-go, size-limited BSON was a no-go, at which point I asked myself if there was a reason to not just use SQLite, and found none. [1] https://sqlite.org/appfileformat.html https://sqlite.org/appfileformat.html
- 28d ago
- nchmy 1mo agoobviously the example is contrived, but it seems strange me that they are not storing the json in its own column - just extracting a single key from it and storing in a generated column. Why not do that in the app code if youre just going to discard the rest of the json? Here's an example i saw yesterday from mariadb, which is improving its json support in its upcoming releases. https://mariadb.com/docs/server/ha-and-performance/optimization-and-tuning/query-optimizations/virtual-column-support-in-the-optimizer#example https://mariadb.com/docs/server/ha-and-performance/optimizat... ``` CREATE TABLE t1 (json_data JSON); INSERT INTO t1 VALUES('{"column1": 1234}'); INSERT INTO t1 ... ``` In order to do efficient queries over data in JSON, you can add a virtual column, and an index on that column: ``` ALTER TABLE t1 ADD COLUMN vcol1 INT AS (cast(json_value(json_data, '$.column1') AS INTEGER)), ADD INDEX(vcol1); ```
- inigyou 1mo agoPostgres does even better and it's available right now. No virtual column needed. CREATE TABLE t1 (data JSONB); INSERT INTO t1 VALUES ('{"column1":1234}'); CREATE INDEX t1column1 ON t1(data->'column1'); SELECT * FROM t1 WHERE data1->'column1' = '1234'; // not sure about data type
- vidarh 1mo ago
- pmkary 1mo agoI remember this getting to the top of HN for at least two more times.
- Jtsummers 1mo agoJust once. But related and similar links show up regularly.
- sohaibqasem 1mo ago[dead]
- rcarmo 1mo agoI'm doing both "documents" and documents (JSON and gzip compressed blobs for emails, office docs, etc.), with the plaintext extracted and run through FTS5. I can't think of another database that would let me do this, plus vector indexing as well. JSON extensibility and virtual columns help _a lot_ with variable metadata.
- desktopentree 1mo ago[flagged]
- wwalexander 1mo ago> it added a killer feature: generated columns It would be super cool if somehow SwiftData could translate computed properties of @Model objects into these generated columns via the #Expression macro!
- retropragma 1mo agoI created `kindstore` for exactly this (only supports Bun currently). I never promoted the project until this comment. Curious if anyone is intrigued? https://github.com/alloc/kindstore https://github.com/alloc/kindstore
- conception 1mo agoSince sqlite people are probably in this thread - why is storing genomic data as a sqlite tar with all the metadata you want in tables a “Bad Idea” (tm)? Like toss a fastq or bam plus all the downstream data, grant info, experiment parameters, specimen info etc etc in a single file easily parsable.
- Hendrikto 1mo agohttps://sqlite.org/appfileformat.html https://sqlite.org/appfileformat.html It is not a bad idea. It is a very flexible and stable format.
- SleepyPenguin 1mo agoI developed an application using zope on the backend and extjs (now Sencha) and SQLite on the front end in 2009. The form + data was stored as strings in the database and then synced to back-end when connected to the internet. It was targeting remote doctors in third world countries who were often offline. Several doctors at that time had told me they wanted to store the medical data in the same format as the intake form mostly because that was what they were used to with paper forms. Soon after, there was a big push for medical ERP and relational databases won over document databases. I bet it would be much easier to build an application like that now (data stored and displayed in same format as collected) but wonder what market would use it.
- Insimwytim 1mo agoIf you applying NOT NULL constraint, why not extract it from json altogether as a separate column? What's the use of it in json? You may construct it back on retrieval, if you need it in results.
- igkougkousis 1mo ago[flagged]
- piterrro 1mo agoI do that in psql and it works really well. But your post got me thinking since I need to find a solution to store content of multiple documents, have a way to do FTS as well as vector similarity. I dont need that for all of the documents at once - I need to do it either for one document or at most couple of documents. Now I'm thinking I could have a separate database file per "batch", store it in object storage and then download on demand and query it as I want. This way I'll not bloat my primary storage size as well as I dont need a special vector DB since sqlite vector search will be enough for up to 50k vectors.