My biggest gripe with ON CONFLICT upserts are the IDs (sequences) having gaps in them. Any good ways to prevent that?
My biggest gripe with ON CONFLICT upserts are the IDs (sequences) having gaps in them. Any good ways to prevent that?
By the time we reached a few thousand entries, we had primary keys in the millions. I personally don't care that there are gaps in the sequence, but gaps of hundreds of thousands definitely leaves a lot to he desired. I think you can circumvent this behaviour by changing from `DO NOTHING` to `DO UPDATE` and doing a dummy write, but that too leaves much to be desired.
I also discovered that `ON CONFLICT` doesn't really work with a high number of concurrent writes. We had to implement our own upsert logic using advisory locks.
-- Will leave gaps
INSERT INTO t (val) VALUES ('abc'), ('def') ON CONFLICT DO NOTHING;
-- Won't leave gaps
INSERT INTO t (val)
SELECT * FROM (VALUES ('abc'), ('def')) AS tmp (val)
WHERE NOT EXISTS (SELECT 1 FROM t WHERE t.val = tmp.val);
https://www.db-fiddle.com/f/6s4uYA987owJxu3CEvfu8t/0Thanks for sharing.
Why do you even need that?
I've worked on various database solutions, both rdbms and analytical and I find sequences to be one of the most misunderstood features in the industry. The only guarantee they make is that they generate unique values. Some of the newer distributed rdbms don't even guarantee they'll be monotonic.
Relying on them generating consecutive values is a sure way to get vendor lock-in to whatever database has made that guarantee.
It 'violates' the principle of least surprise. Intuitively you'd expect `ON CONFLICT .... DO NOTHING` to do nothing, but it will increment the PK every time.
In any bigger project it's just noise and IDs are not helpful information anyway, not even at a glance. It's better to just ignore them, use bigint and move on.