2015-11-03 56 views
7

我有一個相當大的表(大約10億行),我需要將ID類型從SERIAL更新爲BIGSERIAL;猜猜爲什麼?:)。postgreSQL同時將列類型從int更改爲bigint

基本上這可能是與這個命令來完成:

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

然而,將永遠鎖住我的桌子,把我的網絡服務了。

是否有一個相當簡單的方法同時進行此操作(無論它將花費多少時間)?

回答

3

如果沒有外鍵指向您的ID,你可以到舊添加新柱,填充它,放下舊的和新的命名:

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; 
+0

謝謝,這個解決方案是非常優雅。在我看來,仍然存在問題。當我們填充new_id列時,新行將被插入到表中,new_id值將不會被設置,唯一索引創建可能會失敗。 我們可以在插入過程中添加觸發器設置new_id,直到我們在其上添加nexval默認值爲止? –

+0

唯一索引忽略'null'值,因此不需要觸發。 –

+0

如果'alter table my_table add column new_id bigint;'需要很長時間(需要超過1小時但尚未完成)並阻止其他讀取操作? –

相關問題