web-dev-qa-db-ja.com

postgreSQLは列型をintからbigintに同時に変更します

かなり大きなテーブル(約10億行)があり、idタイプをSERIALからBIGSERIALに更新する必要があります。なぜだと思いますか?:)。

基本的に、これは次のコマンドで実行できます。

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

それでも、それによってテーブルが永久にロックされ、Webサービスがダウンします。

この操作を同時に実行する非常に簡単な方法はありますか(それがかかる時間に関係なく)?

20
Pierre Michard

新しい列を追加できるかどうかを指す外部キーがない場合は、それを埋め、古い列をドロップして、新しい名前を古い名前に変更します。

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