After running for a long time, I get more and more holes in the id field. Some tables' id are int32, and the id sequence is reaching its maximum value. Some of the Java sources are read-only, so I cannot simply change the id column type from int32
to long
, which would break the API.
I'd like to renumber them all. This may be not good practice, but good or bad is not concerned in this question. I want to renumber, especially, those very long IDs like "61789238", "548273826529524324". I don't know why they are so long, but shorter IDs are also easier to handle manually.
But it's not easy to compact IDs by hand because of references and constraints.
Does PostgreSQL itself support of ID renumbering? Or is there any plugin or maintaining utility for this job?
Maybe I can write some stored procedures? That would be very nice so I can schedule it once a year.
Assuming your ids are generated from a
bignum
sequence, justRESTART
the sequence and update the table withidcolumn = DEFAULT
.CAVEAT: If this
id
column is used as a foreign key by other tables, make sure you have theon update cascade
modifier turned on.For example:
Create the table, put some data in, and remove a middle value:
Reset your sequence:
Update your data:
The question is old, but we got a new question from a desperate user on dba.SE after trying to apply what is suggested here. Find an answer with more details and explanation over there:
The currently accepted answer will fail for most cases.
Typically, you have a
PRIMARY KEY
orUNIQUE
constraint on anid
column, which isNOT DEFERRABLE
by default. (OP mentionsreferences and constraints
.) Such constraints are checked after each row, so you most likely get unique violation errors trying. Details:Typically, one wants to retain the original order of rows while closing gaps. But the order in which rows are updated is arbitrary, leading to arbitrary numbers. The demonstrated example seems to retain the original sequence because physical storage still coincides with the desired order (inserted rows in desired order just a moment earlier), which is almost never the case in real world applications and completely unreliable.
The matter is more complicated than it might seem at first. One solution (among others) if you can afford to remove the PK / UNIQUE constraint (and related FK constraints) temporarily:
This is also much faster for big tables, because checking PK (and FK) constraint(s) for every row costs a lot more than removing the constraint(s) and adding it (them) back.
If there are FK columns in other tables referencing
tbl.id
, use data-modifying CTEs to update all of them.Example for a table
fk_tbl
and a FK columnfk_id
:More in the referenced answer on dba.SE.
new id column and Foreign Key(s) while the old ones are still in use. With some (quick) renaming, applications do not have to be aware. (But applications should be inactive during the final renaming step)
UPDATE: added the permutation of new_id (after creating it as a serial) Funny thing is: it doesn't seem to need 'DEFERRABLE'.
*This script will work for postgresql
This is a generic solution that works for all cases
This query find the desciption of the fields of all tables from any database.
This query propose a solution to fix the sequence of all database tables (this generates a query in the req field which fixes the sequence of the different tables).
It finds the number of records of the table and then increment this number by one.