Is it normal / recommended to have "id holes" in my user table (rails 3.2 / postgresql)

I am building the main Rails application on Heroku (using postgresql and as PGAdmin db client)

I have a basic user table with a name, email address, password ...

I noticed that when I delete a user (for example, a user with id = 6) and then add new users, the new user is not inserted in id = 6 (I am talking about the first column on the left called pgadmin "id PK Serial"), so which basically I have a lot of holes, because during training I often delete and add users.

So, I get for the id column: id = 1, id = 5, id = 9 id = 10 ... many holes.

Does it matter? Could this affect the db queries I might need later?

If I need to fix this and make db "fill" all id slots, how do I do this?

+4
source share
2 answers

It’s absolutely normal to have “holes” in table identity sequences - even if you never deleted a row. I wrote about this in this earlier answer .

PostgreSQL sequences, at their discretion, are exempt from normal transactional rules. If they were not then, then only one transaction at a time could get the identifier, so you can never have more than one session inserted into the table at a time. This will result in reduced performance.

This is explained in the PostgreSQL tutorial on calling nextval - a call that gets values ​​from sequences:

It is important . To avoid blocking concurrent transactions that receive numbers from the same sequence, the nextval operation is never rolled back; that is, after a value has been selected, it is considered used even if the transaction that later made the next one is aborted. This means that interrupted transactions can leave unused "holes" in the sequence of assigned values.

In theory, PostgreSQL can maintain a list of deleted, abandoned, and unused identifiers, but in practice this is prohibitively expensive in terms of performance and extremely difficult to implement. When an application receives an id with nextval , it can use it at any time in the future, and some applications use this approach, caching identifier blocks for better internal concurrency.

Consider the generated identifiers as a unique line number - and that’s it. This does not tell you how many lines there are. This does not tell you if one row was inserted after another row (for this you can use the created_time , possibly supported by a trigger). It does not tell you whether one row was committed after another row (the xmin columm system tells you that with certain restrictions). All this tells you how to find the string.

Cm:

+4
source

It is normal for Rails to have these spaces between identifiers after deletion.

It’s advisable not to change this, because you may want to track the user's actions later and want to either just go through the logs, or find the corresponding entries in the log, or you can add tables that store the history of what the user did to change the model (for example, when it was deleted / changed).

In both cases, you do not want the ultimate confusion caused by two different instances using the same identifier - hence: do not reuse the ID.

+1
source

Source: https://habr.com/ru/post/1483881/


All Articles