acrolink
I have noticed that the primary_key field (id field) of tables in PostgreSQL doesn’t guarantee auto-incremental values. The rows keys can be for example 1, 2, 3, 5, 6, 9, 10. This is related to the way PostgreSQL works and due to for example validation errors when creating new entities.
My question, how to avoid that? How to make sure that there would be no gaps in the id field? Thank you.
Trending in Questions
I’m working on a project that simulates the bumbl example in the programming phoenix book. It acts almost like an email client. We have a...
New
Hello,
I know there is an approach for handling lists that allows for optimized traversal, but I can’t recall the specific method (somet...
New
I’m seeing that a list inside a Kino.DataTable will be interpreted as a charlist, even if the Kino.configure() is set to charlists: :as_l...
New
So my question is quite simple and i have found no conclusive answer on forum, google or AI.
Should we use :erlang.float for Integer to ...
New
Documentation
While reading the Scoped Routes section, I noticed that the documentation currently refers to a problem without explainin...
New
Hi, I’ve just set up an application with ash_authentication. There is only magic link strategy for now, so there is no confirmation add o...
New
If a change or preparation module uses Ash.Changeset.get_argument/2 or Ash.Query.get_argument/2 (or any of the other get_argument functio...
New
Other Trending Topics
I am happy to introduce the very α version of the new programming language compiled to BEAM.
Welcome Cure.
It has literally three kille...
New
Hi there! We created Gust: A task orchestrator inspired by Airflow.
For those who have never heard about Aiflow, it’s a Python-based wor...
New
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
With AI doing more of the implementation work, I’ve been wondering how much coding I should deliberately keep doing myself.
My main conc...
New
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #library
- #deployment
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixirconf-us
- #ai
- #blog-post
- #elixir-ls
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #hex
- #security
- #metaprogramming










Showing Posts 14 to 5- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
OvermindDL1
UPDATE ... RETURNINGwill, but rarely do I ever update a single table at a time, transactions are almost always necessary for data consistency unless it’s an exceptionally simple database that isn’t using the database features… In addition, the primary key is rarely updated, especially as manually as that would be done. Once transactions are involved this will cause major issues either in terms of handling no concurrency or values getting out of sync.acrolink
Thank you very much. I have done something similar with Phoenix updating the sequence but doing this with a PostgreSQL procedure seems more appropriate.
slashdotdash
No, the
UPDATE…RETURNINGstatement supports concurrent transactions, but will block until the first update completes. After it commits or aborts, the next transaction can continue with the next value, no gaps. This behaves like a single threaded writer. It’s different from sequences which are assigned outside of a transaction for high performance.OvermindDL1
You’d have similar issues on MySQL as well. PostgreSQL’s style is what has to be done when your sql server supports transactions.
And then you conflict when transactions happen, so one will fail when multiple happen at the same time.
benwilson512
Again, what is your actual use case here?
slashdotdash
You can use a separate counter table and either a Postgres function or a Common Table Expression (CTE) to update the counter value during insert into your target table.
Using a Postgres function
Create a “counter” table containing a single “last value” row:
Create a
get_next_idfunction:Create your desired table to use the gapless sequence:
Usage:
Using a CTE
Use a separate “counter” table and a Common Table Expression (CTE) to update the counter value during insert into your target table.
Create a “counter” table containing a single “last value” row:
Create your desired table to use the gapless sequence:
Usage:
With both approaches the
UPDATE…RETURNINGquery will block any other update to thecountertable, thus guaranteeing a gapless sequence. You can test this by attempting to run the query concurrently usingBEGIN;but not committing. You’ll notice that the second query is blocked until the first commits (or aborts).This also means that if the first query’s transaction is aborted (using
ROLLBACK) the second query can continue and will be assigned the next value, no gaps. Unlike using a traditional Postgres sequence which is not transactional.A caveat is that if you delete a row from the table you will then have gaps. This can be prevented with a rule to prevent deletion from the table:
Kurisu
I don’t really know how MySQL is different in this case, but it seems to me that it won’t fill ever at least the gaps due to records deletion. I think the way those SQL engines work is optimal to make quick inserts instead of checking first, gaps of freed ids.
One tricky way I can think about, If the behaviour you want is really important, would be generating the ids yourself based on the current max ID, then if insert fails due to another concurrent insert, you’ll re-acquire the new max ID and retry the insert until it gets done.
preciz
That could introduce potentially more issues. Especially that if this particular problem will be solved maybe the trade offs will not worth it.
Instead would you describe why the gaps are a problem?
Maybe you could reduce the gaps by more validations in the application?
acrolink
Maybe the simplest solution is to simply migrate to
MySQL.al2o3cr
What if I do the insert that gets ID 4 in a transaction that doesn’t commit for several minutes? What ID should inserts in other transactions taking place at the same time get? What if the transaction where I inserted ID 4 eventually rolls back?
“Max ID” is not a straightforward concept once MVCC and transactions are involved. See the notes in the Postgres docs for
CREATE SEQUENCEfor additional thoughts. Big takeaway:(emphasis mine)