News for hackers. Stuff that matters.
Re:Many small queries are efficient in SQLite by millstone on Tuesday February 16, 2021 @01:57AM (#26151589)
Good observations from a MySQL perspective. Any thoughts from the other end, where the alternatives are JSON or XML or ZIP? SQLite tries hard to convince you to use it as an application file format, but it looks like a giant black box of overkill: why incorporate its 200k SLOC when the alternatives are a fraction of the size?
Re:Many small queries are efficient in SQLite by chousuke on Tuesday February 16, 2021 @02:15AM (#26151665)
Is 200kLOC really a lot? Lots of software nowadays has hundreds of megabytes of dependencies, and people seem to be fine with that. Not that I think having tons of dependencies is really a good thing, but for an application that needs a file format, SQLite is a very sensible dependency.

neither XML, JSON nor zip solve the problems SQLite does, though; if you use plain old files, you need to make sure any changes you make actually end up on the disk, consistently. This is not easy to do. It also solves any consistency issues that might stem from someone reading the data while you're writing it.

On top of being just better, having a relational model for your data gives you much more freedom to use said data; you'll be able to do things efficiently that might require restructuring your JSON or XML format. Personally, I love SQLite-based application formats because I can explore them with SQL, which is often much easier than trying to make sense of a custom JSON or XML schema.

Re:Many small queries are efficient in SQLite by millstone on Tuesday February 16, 2021 @02:48AM (#26151806)
Good reply, thank you.

Yes 200k SLOC is huge (modern development practices notwithstanding). SQLite creates temporary files at whim - nine different kinds! https://sqlite.org/tempfiles.html

I know how to atomically write a JSON file. But when I read, for example:

"The temporary files associated with transaction control, namely the rollback journal, super-journal, write-ahead log (WAL) files, and shared-memory files, are always written to disk. But the other kinds of temporary files might be stored in memory only and never written to disk. Whether or not temporary files other than the rollback, super, and statement journals are written to disk or stored only in memory depends on the SQLITE_TEMP_STORE compile-time parameter, the temp_store pragma, and on the size of the temporary file..."

My eyes have completely glazed over. If I add this to my app, what will it actually do? How can I even know?

Re:Many small queries are efficient in SQLite by iainmerrick on Tuesday February 16, 2021 @03:34AM (#26152037)
I know how to atomically write a JSON file.

Are you sure? I’ve had a lot of trouble getting that to work reliably myself across multiple OSes. (In hindsight I wish I’d used SQLite!) This article gives a good explanation of the many difficulties:

https://danluu.com/deconstruct-files/

My eyes have completely glazed over. If I add this to my app, what will it actually do? How can I even know?

Well, fundamentally it’s very hard to get it exactly right, and I imagine that’s why the implementation is a little involved.

But you could a) read through those docs, lengthy though they are, and/or b) trust the many testimonials saying SQLite is very, very robust and reliable.

Re:Many small queries are efficient in SQLite by scaladev on Tuesday February 16, 2021 @05:10AM (#26152577)
Here's another good review of the pain you get if you want to get your data to disk safely.

(SQLite does this for you automatically, BTW.)

"Ensuring data reaches disk"

https://lwn.net/Articles/457667/

Re:Many small queries are efficient in SQLite by ori_b on Tuesday February 16, 2021 @09:50AM (#26154318)
> (SQLite does this for you automatically, BTW.)

Unless you're on nfs. Remote file locking is hard, and I don't think that any nfs implementation has gotten to the point where you can trust SQLite on it.

SQLite does updates in place, which I would trust far less than a rename call.

Re:Many small queries are efficient in SQLite by millstone on Tuesday February 16, 2021 @05:04AM (#26152548)
> Are you sure?

No, and anyone who says yes is lying. (Lockless NFS exists and is no fun.)

> Well, fundamentally it’s very hard to get it exactly right, and I imagine that’s why the implementation is a little involved

SQLite has set itself the horrible task of updating files in-place. I know of two reliable, simpler alternatives:

1. Appending to files through O_APPEND

2. Rewriting files through rename()

If SQLite has different magic syscalls then I would very much like to learn.

Re:Many small queries are efficient in SQLite by Someone on Tuesday February 16, 2021 @05:42AM (#26152722)
I don’t think you can atomically append more than one byte to files in unixes (the write call can return after having written some but not all requested bytes)

(Haven’t googled, but if that’s possible, I don’t see why write would have that limitation)

Re:Many small queries are efficient in SQLite by LunaSea on Tuesday February 16, 2021 @07:37AM (#26153305)
Interesting and confirmed in the write() syscall man pages. Thanks!

Do you have any other resources regarding these types of low level "gotchas"?

I remember PostgreSQL having such an issue two years ago for example.

Re:Many small queries are efficient in SQLite by millstone on Tuesday February 16, 2021 @06:23AM (#26152923)
Yeah, and eventually we reach the best-effort bedrock. Maybe the file is on a NFS mount, you call write(), it goes over the wire, who knows what happens!
Re:Many small queries are efficient in SQLite by moosebear847 on Wednesday February 17, 2021 @07:25AM (#26165584)
Dan luu's article mentioned these two options as unreliable. What's the reason for the disparity?
Re:Many small queries are efficient in SQLite by exikyut on Tuesday February 16, 2021 @04:02AM (#26152197)
> If I add this to my app, what will it actually do? How can I even know?

Be really, really, *really*, unambiguously sure about whether your data was written or not, AND have high confidence that I/O errors (eg, power loss) in the middle of does of deletes won't scramble (or truncate) existing data.

What you're looking at is the complexity required to solve for the wonderful tornado of "but it's my data really written???". But you don't have to deal with SQLite's implementation details in order for it to do its thing, which is what makes it so awesome (given is public domain status, what's more!).

Re:Many small queries are efficient in SQLite by pjc50 on Tuesday February 16, 2021 @03:51AM (#26152149)
> I know how to atomically write a JSON file.

Sure. But that forces you to rewrite all the data at once. Once it becomes large or you require more frequent changes, that will impact performance.

Re:Many small queries are efficient in SQLite by yarcob on Tuesday February 16, 2021 @03:03AM (#26151877)
File formats based on ZIP files only work for small files. For big files you have huge overheads; opening and saving a moderately sized documents takes seconds (vs. milliseconds for writing changes to an SQLite database). There's a reason why Excel files are limited to a million rows, while Access databases aren't.

The complexity of including SQLite is trivial for practical purposes; it's already available on many systems, and if not you can include it by adding a single C file to your project.

Setting up a workflow for Google Protocol Buffers (another popular alternative for document file formats) is a lot more complex than building or linking with SQLite, and it doesn't stop people from using them.

One thing that speaks for SQLite is the quality of the project; it's one of the best maintained Open Source projects with fantastic quality assurance and support for almost every OS. This means that you are unlikely to run into issues compiling or working with SQLite, like you might have with alternative libraries like libxml2 or jsonc (which are still great libraries!!).

EDIT: The big downside of SQLite is that it's unsuitable for documents that are exposed to the user because of the temporary files (like the WAL). If you have a ZIP based file format that you atomically rewrite from scratch on every save, it's almost impossible to corrupt. Your users can just take the file and email it and nothing bad will happen. I'm not sure what happens if you email an SQLite database file that is currently being used. I've done that in the past and have been surprised that some data seemed to be missing, but I don't recall the details. Hence SQLite is often used for application data files that are not directly exposed to the user.

Re:Many small queries are efficient in SQLite by slaymaker1907 on Tuesday February 16, 2021 @05:04PM (#26159344)
You could get SQLite to work as document files exposed to the user so long as you use sessions[1]. When a file is opened, copy the DB to a temporary file or to use memory and write all changes during operation to this new DB, recording them all in a session. When the user explicitly saves a document, apply the session to the real DB.

[1]: https://www.sqlite.org/sessionintro.html#:~:text=1%20Introdu...

Re:Many small queries are efficient in SQLite by yarcob on Wednesday February 17, 2021 @09:44AM (#26166793)
That doesn't sounds like it would just combine the drawbacks of both approaches: You end up with slow open/save operations, and the writes to the db still aren't necessarily atomic (eg. if a user copies the file while changes are being applied)
Re:Many small queries are efficient in SQLite by ak217 on Tuesday February 16, 2021 @02:10AM (#26151646)
JSON/XML quickly stop being alternatives as soon as you need any sort of index, a memory-mapped/on-disk data structure that doesn't have to be loaded into memory, transactional or even just incremental writes. ZIP is not even directly comparable.
Re:Many small queries are efficient in SQLite by tonyedgecombe on Tuesday February 16, 2021 @02:30AM (#26151725)
That's not normally what you need for an application format though is it.
Re:Many small queries are efficient in SQLite by rini17 on Tuesday February 16, 2021 @02:50AM (#26151818)
It's becoming normal, as users coming from phones aren't trained to use "save" function and expect every individual change to persist.

I actually consider that a good thing. Doing everything in volatile memory until user asks otherwise is a relic from diskette era.

Re:Many small queries are efficient in SQLite by em500 on Tuesday February 16, 2021 @05:03AM (#26152545)
It's not limited to phone users. I've been using computers since the 1980s (C64), and I appreciate not needing to habitually keep pressing "save" every few seconds in Google Docs or macOS Notes.
Re:Many small queries are efficient in SQLite by wheybags on Tuesday February 16, 2021 @09:18AM (#26154054)
#1 best jetbrains idea feature IMO - save on focus lost. Just alt tab into your app, or into your terminal to git commit, no worrying about "did I remember to ctrl-s".
Re:Many small queries are efficient in SQLite by mmcdermott on Tuesday February 16, 2021 @11:41AM (#26155746)
I grew up in the Win 3.1-Win 98 era. I don't think the save reflex will ever quite go away. :)
Re:Many small queries are efficient in SQLite by wtetzner on Tuesday February 16, 2021 @05:42PM (#26159721)
Sometimes when I'm working on paper I reach for ctrl+s out of reflex ;)
Re:Many small queries are efficient in SQLite by folmar on Tuesday February 16, 2021 @12:53PM (#26156673)
It is a nuisance unless you have undo that is persistent. Phone-app likes have barely any undo.

For example: cut some content from a file to paste it somewhere else. Now the program saves and system crashes.

Re:Many small queries are efficient in SQLite by ymbeld on Tuesday February 16, 2021 @06:28AM (#26152949)
It’s bad enough to have to keep pressing Save manually, but I also have to do it regularly while using LibreOffice Calc since it keeps crashing. :-)
Re:Many small queries are efficient in SQLite by dragonwriter on Tuesday February 16, 2021 @03:39AM (#26152078)
> That’s not normally what you need for an application format though is it.

Well, it depends what you mean by “need”. But continuous, incremental updates generally provide a much better user experience, either instead of or in addition to active “save” actions.

So, yeah, I think its exactly something that is commonly desirable in a file format for maintaining application state, even if there is a different interchange format that the application produces/consumes as a static input or output.

Re:Many small queries are efficient in SQLite by imtringued on Tuesday February 16, 2021 @09:56AM (#26154392)
During the alpha Minecraft divided the world into 16x16x128 grids of blocks called chunks. Each chunk was its own file. Large worlds suffered from very poor performance because there were tens of thousands of files in a single folder.

Some random modder basically just put multiple chunks into one file so that each file is 2MB. If Notch had just put the game world into a SQLite database he wouldn't have had to reinvent the wheel. There are games that did that, such as the alpha of Cube World and they work just fine.

Heck, notch went one step further and invented NBT aka named binary tag which is basically a weirdo binary file format that stores JSON like data.

Re:Many small queries are efficient in SQLite by iforgotpassword on Tuesday February 16, 2021 @11:50AM (#26155888)
> Large worlds suffered from very poor performance because there were tens of thousands of files in a single folder.

It was using subdirs for the chunks, two levels iirc, one was chunkX % 36, the next level chunkY % 36. So there weren't that many files per directory. The slowness came from the overhead of opening, read/write and closing so many files all the time.

> Some random modder basically just put multiple chunks into one file so that each file is 2MB.

Almost, it wasn't limited by file size, it was putting 32*32 chunks into one file that was similar to a simple file system. The format of the individual chunks within that file stayed almost the same. Yet it performed much better.

NBT is indeed a little weird but fairly straight forward overall, I guess designing and implementing it just scratched an itch. It was a hobby project after all.

Re:Many small queries are efficient in SQLite by slaymaker1907 on Tuesday February 16, 2021 @05:06PM (#26159361)
I'm actually currently working on a user mode FS using Dokan for Windows that saves everything to a SQLite file for similar reasons. NTFS just doesn't do well at all with lots of small files.
Re:Many small queries are efficient in SQLite by fomine3 on Wednesday February 17, 2021 @12:22AM (#26163017)
Interesting. Did you tested any performance by non-NTFS?

I remembered this post. https://github.com/microsoft/WSL/issues/873#issuecomment-425...

Re:Many small queries are efficient in SQLite by dragonwriter on Tuesday February 16, 2021 @03:31AM (#26152020)
> Any thoughts from the other end, where the alternatives are JSON or XML or ZIP?

ZIP isn’t a format alternative, its just a compression and/or packaging technique for files which you still need to choose a format for.

JSON/YAML/XML are great for input and output formats, but not great for continuous, random read/write access.

Re:Many small queries are efficient in SQLite by millstone on Tuesday February 16, 2021 @03:40AM (#26152084)
My understanding is that SQLite doesn't impose any format either?
Re:Many small queries are efficient in SQLite by dragonwriter on Tuesday February 16, 2021 @06:01AM (#26152820)
> My understanding is that SQLite doesn't impose any format either?

That's true that you can stuff any kind of string/blob data into any column of any table, so, yes, you still have to determine the data schema with sqlite much as you do with JSON, XML, or even CSV. I mean, I could have a CSV where each element is a base64-encoded ZIP containing sqlite database files that are each a single table with a single column of JSON files, each of which contains a JSON array of strings with XML documents in them.

But that's usually not something people would mean if they said their app was using CSV as it's data storage format, nor is the version stripping out CSV on the top what people would mean if they say they are using SQLite.

With ZIP, you have to decide the format(s) for the file(s) in the ZIP, their hierarchical structure, and, if the files aren't themselves the atomic data elements, the schema applicable to each file.

Furthermore, in discussion of performance characteristics and other aspects of suitability, ZIP adds overhead, but you still also need to consider the access properties of the contained files.

Re:Many small queries are efficient in SQLite by mb7733 on Tuesday February 16, 2021 @05:12AM (#26152591)
I'm genuinely curious what you mean by this. Of course SQLite imposes a file format... That format is a SQLite database
Re:Many small queries are efficient in SQLite by Dylan16807 on Tuesday February 16, 2021 @05:45AM (#26152738)
> Of course SQLite imposes a file format... That format is a SQLite database

Well this is in a context that rejects zip as being a format. Do you do that? If the answer is no then skip the rest of my post and just note that they're talking about a different definition of 'format'.

-

But in that context:

The amount of structure imposed on you by the sqlite database format is not much more than the structure imposed on you by a zip. I think it's fair to rate them similarly as formats. A zip file is basically a key-value store.

"Zip full of csvs", while awful to use, would impose about the same amount of structure as sqlite does: not much. And zip+csv is not much more elaborate than zip on its own.

Re:Many small queries are efficient in SQLite by samatman on Tuesday February 16, 2021 @05:31PM (#26159591)
In SQLite, I can have a table with a row which is `flag INTEGER NOT NULL CHECK flag == 0 or flag == 1 DEFAULT 0`

Surely this is more structure than a ZIP file, which is merely a way of compressing a directory of files into a single entity, can provide?

Sure the INTEGER part doesn't really do anything...

Re:Many small queries are efficient in SQLite by Dylan16807 on Wednesday February 17, 2021 @02:09AM (#26163589)
That's a feature of the database engine, not the file format. You could attach a similar database engine to a zip backend.
Re:Many small queries are efficient in SQLite by samatman on Wednesday February 17, 2021 @02:50AM (#26163795)
This is an asinine objection.
Re:Many small queries are efficient in SQLite by Dylan16807 on Wednesday February 17, 2021 @03:05AM (#26163881)
I have a better one, if you want it.

A configuration like that comes from the program using sqlite. Just adding sqlite into a system doesn't set up any data formatting like that. Sqlite itself gives you a blank canvas. And a blank canvas is not much of a data format.

Re:Many small queries are efficient in SQLite by samatman on Wednesday February 17, 2021 @05:19PM (#26172587)
You're wrong about this.

The SQLite data format includes the schema, in plain ASCII. This self-documenting nature makes it an excellent data format, I've taken advantage of it numerous times in making use of SQLite-based application file formats.

SQLite is put forth as a basis for an application file format, and by definition it must be sufficiently flexible to accommodate any application. But by including the schema, it is self-documenting as to what the structure is, which ZIP isn't and can't be. QED.

Re:Many small queries are efficient in SQLite by millstone on Tuesday February 16, 2021 @06:12AM (#26152872)
I hope to make the modest point that, if you package your data in a SQLite file or a zip file, then you have both packaging and data problems.

MyCoolSQLApp may read and write a SQLite file with its own schema, but it can't handle an arbitrary SQLite file. Likewise MyCoolZipApp can't handle an arbitrary zip file.

Re:Many small queries are efficient in SQLite by mb7733 on Wednesday February 17, 2021 @11:53PM (#26175989)
I'm not clear on the point here. You can make an application that handles arbitrary SQLite files, (for example: the SQLite shell, or a GUI database broswer), or you can make an application that only uses SQLite files with certain content/schema. Does this mean that SQLite does or does not define a file format?

If not, what do you call the specification of how data is stored in a SQLite file besides a 'file format'?

Re:Many small queries are efficient in SQLite by 7steps2much on Tuesday February 16, 2021 @02:13AM (#26151656)
It all depends on how much/how complex data you have. SQLite is a database after all, you can query it with SQL and do lots of fancy stuff that might be hard to do with regular file formats like JSON or XML.

If you just need a config file or only have a small amount of data you can use XML/JSON files that you parse yourself. If you are going to have loads of data that needs some structure (for example messages in a messaging app) i would use SQLite.

Re:Many small queries are efficient in SQLite by kstrauser on Tuesday February 16, 2021 @02:28PM (#26157737)
There's an enormous amount of comments and tests in that codebase. As installed on my Mac, sqlite comprises a 1.3MB command line utility and a 1MB shared library. That's absolutely tiny given the functionality it provides.
Re:Many small queries are efficient in SQLite by petre on Tuesday February 16, 2021 @02:24AM (#26151702)
Go ahead and use text files and then have fun with data corruption issues. We use CSV for sending commands to IoT devices and it's an issue. If this had been done with SQLite, then there were at least no data corruption issues. One could even use SQLite as a storage container for JSON if one whises to do so. They even have an extension that aids it with an useful set of functions:

https://www3.sqlite.org/json1.html

Re:Many small queries are efficient in SQLite by JamesSwift on Tuesday February 16, 2021 @09:08AM (#26153967)
The JSON features of SQLite are extremely robust and performant. There is no reason to use raw JSON as the storage when you can just shove it into SQLite and lose almost nothing.
Re:Many small queries are efficient in SQLite by millstone on Tuesday February 16, 2021 @03:02AM (#26151870)
This sounds like your issue is avoiding data corruption: then atomic writes are sufficient, you don't need a SQL parser or query optimizer or etc.
Re:Many small queries are efficient in SQLite by petre on Tuesday February 16, 2021 @06:17AM (#26152890)
Not only that, it enables us to to CRUD operations, list the commands, sort them by time, do limits, pagination, bundle a bunch of commands that enable a certain functionality in a transaction etc. SQLite has all of those and more and also avoids data corruption issues by design. Anyway, the path we took was to move everything to MySQL just because most of the other data is also in a MySQL database. Otherwise we would have definitely used SQLite.
Re:Many small queries are efficient in SQLite by Scarbutt on Tuesday February 16, 2021 @02:02AM (#26151609)
How do you create structure data with ZIP?

why incorporate its 200k SLOC when the alternatives are a fraction of the size?

Performance, ACID and a superior declarative query language.

Re:Many small queries are efficient in SQLite by millstone on Tuesday February 16, 2021 @02:22AM (#26151688)
ZIP files are not a database: they are more like a directory hierarchy. But maybe all I need is named blobs: no query language parser, optimizer, indexing, etc.

SQLite positions itself as an improvement over ZIP for application file formats: https://www.sqlite.org/appfileformat.html . But minzip is so much smaller, easier to understand, debug and ship. So why use SQLite for an app if ZIP suffices?

Re:Many small queries are efficient in SQLite by setr on Tuesday February 16, 2021 @03:59AM (#26152184)
If you’re talking about like cbr archives, you’re right. It’s comparing against usages like word/excel, which store a bunch of XML in an archive and call it a day.

If you’re not reading and writing out application state, then yes, you don’t need something to manage your non-existent state

Re:Many small queries are efficient in SQLite by realdense on Tuesday February 16, 2021 @02:05AM (#26151624)
Depends on your use case. XML and JSON are great for applications with simple data stores, having done this myself. But if you foresee a need for complex queries or locking and threads then SQLite might be a good choice.