web-dev-qa-db-fra.com

postgreSQL change simultanément le type de colonne de int en bigint

J'ai une assez grande table (environ 1 milliard de lignes) et j'ai besoin de mettre à jour le type d'ID de SERIAL vers BIGSERIAL; devine pourquoi?:).

Fondamentalement, cela pourrait être fait avec cette commande:

execute "ALTER TABLE my_table ALTER COLUMN id SET DATA TYPE bigint"

Néanmoins, cela verrouillerait ma table pour toujours et mettrait mon service Web hors service.

Existe-t-il un moyen assez simple de faire cette opération simultanément (quel que soit le temps que cela prendra)?

20
Pierre Michard

Si vous n'avez pas de clés étrangères pointant votre identifiant, vous pouvez ajouter une nouvelle colonne, la remplir, supprimer l'ancienne et renommer le nouveau en ancien:

alter table my_table add column new_id bigint;

begin; update my_table set new_id = id where id between 0 and 100000; commit;
begin; update my_table set new_id = id where id between 100001 and 200000; commit;
begin; update my_table set new_id = id where id between 200001 and 300000; commit;
begin; update my_table set new_id = id where id between 300001 and 400000; commit;
...

create unique index my_table_pk_idx on my_table(new_id);

begin;
alter table my_table drop constraint my_table_pk;
alter table my_table alter column new_id set default nextval('my_table_id_seq'::regclass);
update my_table set new_id = id where new_id is null;
alter table my_table add constraint my_table_pk primary key using index my_table_pk_idx;
alter table my_table drop column id;
alter table my_table rename column new_id to id;
commit;
13