2017-05-23 8 views
1

私は "親テーブル"とパーティションテーブルをたくさんのカラムで作成していますが、今度はカラムをVARCHAR(32)からTEXTに変更する必要があります。ロックテーブルなしでPostgreSQLのVARCHARをTEXTに変更

私は親を変更するので、すべてのパーティションも変更されます。

しかし、テーブルにはこの列に2つのユニークなインデックスと1つのインデックスがあります。また、この1

ALTER TABLE my_schema.my_table 
ALTER COLUMN column_need_change TYPE VARCHAR(64) USING 
column_need_change :: VARCHAR(64); 

:私はこのソリューションを参照してください

ALTER TABLE my_schema.my_table 
ALTER COLUMN column_need_change TYPE TEXT USING column_need_change :: TEXT; 

このクエリは、テーブルロック

UPDATE pg_attribute SET atttypmod = 64+4 
WHERE attrelid = 'my_schema.my_table'::regclass 
AND attname = 'column_need_change '; 

をしかし、私は、このソリューションを嫌います。

どのように変更することができますVARCHAR(32)タイプにTEXTロックテーブルなしで、私は更新の間にテーブル内のいくつかのデータをプッシュし続ける必要があります。

私のPostgreSQLのバージョン:9.6

EDIT:クエリが間に私のテーブルロック

ALTER TABLE my_schema.my_table 
ALTER COLUMN column_need_change TYPE TEXT USING column_need_change :: TEXT; 

これは私が取るソリューションである2.6百万人の行に対して1メートル52Sの548msをしかし、それは大丈夫です。

答えて

2

サポートされていて安全な形式はALTER TABLEです。 varchartextのディスク上の表現は同じですので、ACCESS EXCLUSIVEテーブルロックが取得された時点で分割されて実行されますので、ではありません。

取引が短ければ短い取引が発生しますが、ALTER TABLEはすべての取引が完了するのを待ちます。

システムカタログを使用することは危険であり、自己責任で行ってください。

あなたは

UPDATE pg_attribute 
SET atttypmod = -1, 
    atttypid = 25 
WHERE attrelid = 'my_schema.my_table'::regclass 
    AND attname = 'column_need_change'; 

で逃げるかもしれない。しかし、それは何かを壊した場合、あなたは作品&hellipを手にします。

+0

私が間違っていると誰かが私に修正してください!)varcharフィールドの長さ制限は事実上許容される値の制約であり、列はディスクに格納されます。他のほとんどのDBMSでは、最初の指定された制限のために十分な空き容量があるだけで、行がディスク上に配置されるため、その長さを増やすと*表の書き換えが必要になります。 – IMSoP

+0

あなたはPostgreSQLに関する限りです(他のDBMSについてはわかりません)。 –

+0

@IMSoP:OracleとSQL Serverは、変更が "互換性がある"場合(例: 'varchar(20)'から 'varchar(500)'へ –

関連する問題