News for hackers. Stuff that matters.
Re:Many small queries are efficient in SQLite by mikeyjk on Tuesday February 16, 2021 @07:35AM (#26153294)
I've never worked at a place that doesn't use them. What if the 3rd insert in a series fails and consequently writes the wrong thing down on the 4th with an update?

That's just my experience so I guess it may be meaningless but I'm surprised to hear it may not be often used.

Re:Many small queries are efficient in SQLite by konha on Tuesday February 16, 2021 @08:19AM (#26153555)
> I've never worked at a place that doesn't use them.

Consider yourself lucky then. I know of a place that doesn’t use transactions in a homegrown ERP solution, of all things.

Re:Many small queries are efficient in SQLite by FpUser on Tuesday February 16, 2021 @09:56AM (#26154386)
I've seen all kinds of wonders during my life so this one is no surprise. If however someone is doing stupid things it is their problem. They're free to complain to themselves.
Re:Many small queries are efficient in SQLite by mumblemumble on Tuesday February 16, 2021 @10:35AM (#26154819)
Tangentially - it may be their problem, but I hesitate to say it's their fault. I'm continually dismayed at how spotty and superficial education about how to use an RDBMS can be. Even in formal education on the subject.
Re:Many small queries are efficient in SQLite by FpUser on Wednesday February 17, 2021 @04:56AM (#26164674)
It does not take PhD and rocket science for one to figure that sometimes operations must be bunched and executed with success/failure as a single unit. That would come as a business requirements. For curious person it would not take much to do some search on a subject and discover and read about transactions.
Re:Many small queries are efficient in SQLite by slaymaker1907 on Tuesday February 16, 2021 @04:22PM (#26158957)
You hardly ever need transactions if you track validity explicitly in your schema.

Suppose T1 has a 1-many relationship with T2. Declare in your assumptions that any rows in T2 with no corresponding valid row in T1 are not valid.

Additionally, have an is_valid field on T1 so selecting all valid data from T2 is done with "select * from T2 inner join T1 on T2.t1id = T1.id where T1.is_valid".

To insert data, insert a row into T1 first but initially have is_valid be false. Then insert all necessary data into T2. Finally, do an update and change the original row in T1 to have is_valid be true.

For deletions to T1, just do an update and set is_valid to false. Thanks to the validity logic, this has the effect of also invalidating all T2 rows.

Updates are trickier, but you can allow them to work without transactions by having two ids for for every table. The first id is the one we worked with before which is used for joins. The second id is used by applications to look for explicit records. Therefore, just never do any updates aside from the one setting is_valid to true (which is really storage logic and not application logic). Instead, just insert a new row into T1 whenever you want to update something in T1. The final update now just needs to flip the is_valid bit for the old row and the new row and will also need to verify that the old row is valid as well as any other rows the current update relies on (basically need to turn it into complex CAS).

All of this is pretty messy, but it does let you have CRUD without any transaction support from your DB. Also, even if your DB has transactions, this scheme has the advantage of being lock-free so your application cannot deadlock.

If you have many updates/deletes, you can do garbage collection either by allowing the GC to use a transaction or by changing adding in a check for insertions to T1 that verify the number of associated rows in T2 before setting is_valid.

Unfortunately, while updates and inserts with GC can still be lock-free, they are not wait-free since an insert or update can fail. If you never do updates or GC though, this is actually wait-free and guarantees that every create, read, and delete operation will succeed in the absence of hardware/network failures.

Still, this overhead probably isn't worth it unless you already need to track the history explicitly for auditing or something. At the company where we used this, we didn't have an is_valid row, we had valid_from and valid_to which were timestamps.

Re:Many small queries are efficient in SQLite by rc48 on Thursday February 18, 2021 @03:57AM (#26177541)
Same as @mikeyjk! Can you point toward more information on this topic? The applications I'm dealing with in my day job are constantly plagued by deadlocks in the database surrounding bulk transactions. I've theorized that a "T1 1-many T2" refactoring of the tables - like what you've described - might be a solution , but haven't settled on how to implement. Would absolutely love to learn more on this esoteric, hard-to-google topic.
Re:Many small queries are efficient in SQLite by mikeyjk on Sunday February 21, 2021 @10:04PM (#26220372)
I guess I'm not sure how you can get away without needing transactionality for these extra columns / is_valid columns
Re:Many small queries are efficient in SQLite by hnlmorg on Wednesday February 17, 2021 @06:46AM (#26165353)
All of this sounds like a lot of additional work just to provide some of the functionality transactions provide out of the box. And I say "some" because you've not addressed rollbacks.

That said, it's still an interesting thought experiment so glad you shared.

Re:Many small queries are efficient in SQLite by mikeyjk on Tuesday February 16, 2021 @11:18PM (#26162638)
Wow, this has broken my brain but has really piqued my interest - thanks. Do you have any reading on this topic / strategy to help a mouth breather like me out?
Re:Many small queries are efficient in SQLite by rc48 on Thursday February 18, 2021 @03:59AM (#26177550)
My sentiments exactly!