PostgreSQLフィールドタイプをintからbigintに変更

5837 ワード

現在pgのバージョンではintからbigintを変更するにはrewriteテーブルが必要であり、テーブルがブロックされ、使用できません.しかし、他の方法を考えてもいいです.この問題は,現網pgがシーケンスを使用している場合に発生する.intの最大値は21億程度であり,自増列がプライマリキーであることが多いため,最大値に達するとデータが挿入できない.一般的にはbigintのタイプを変更しますが、直接行うとテーブルがロックされ、現網の使用に影響します.ここで2つのブロックに分けて見ると、1、パーティションテーブル(シーケンスの変更):パーティションテーブルではシーケンスをループ形式に直接変更でき、最大値はintの最大値に設定されます.単一のパーティションテーブルではint値が切れないためです.
alter sequence seq_name MAXVALUE 2147483647  CYCLE;

ここでは、hashパーティションテーブルの場合、フィールドタイプのみを変更できる日または月ごとのパーティションテーブルに適用されます. 
 
2、非パーティション表(bigintに変更)
テーブルの作成時にserialを使用する可能性があるため、フィールドidが削除されると、前のシーケンスも削除されます.次の手順では、new_idにnot null制約がない場合、not nullのレコードがあるかどうかを全テーブルスキャンでチェックします.pgは、レコードがnot nullであるかどうかをチェックする操作が速いが、このステップは長時間ロックされる(レコード数によって異なる).
alter table table_name add  column new_id bigint;

---    new_id
do language plpgsql $$
declare
i int;
begin
for i in 0..1000 loop
update table_name set new_id = id where id >= min(id)+ (max(id)-min(id))/1000*i and id< min(id) + max(id)-min(id))/1000*(i+1);
end loop;
end $$;

create unique index CONCURRENTLY on table_name(new_id);

BEGIN; ALTER TABLE table_name DROP CONSTRAINT table_name_pkey; CREATE SEQUENCE table_name_new_id_seq; ALTER TABLE table_name ALTER COLUMN new_id SET DEFAULT nextval('table_name_new_id_seq'::regclass); UPDATE table_name SET new_id = id WHERE new_id IS NULL; ALTER TABLE table_name ADD CONSTRAINT table_name_pkey PRIMARY KEY USING INDEX table_name_pk_idx; ALTER TABLE table_name DROP COLUMN id; ALTER TABLE table_name RENAME COLUMN new_id to id; ALTER SEQUENCE table_name_new_id_seq RENAME TO table_name_id_seq; SELECT setval('table_name_id_seq', (SELECT max(id) FROM table_name)); COMMIT;

 
また、データ辞書を修正することで同様の操作が可能ですが、推奨されず、メタデータの破損を引き起こす可能性があります.
 
転載先:https://www.cnblogs.com/xiaotengyi/p/9636444.html