4

Postgres に ~ 1M 行のテーブルがあります。このテーブルの 1 つの列には、SMALLINT データが格納されます。ここで、予想よりも大きい数値をこの列に格納する必要があります。この既存の列を SMALLINT から INTEGER に変換するにはどうすればよいですか?

4

2 に答える 2

12

smallint列のデータ型を からに変更する必要がありますinteger:

alter table T alter C type integer

T と C は、それぞれテーブルと列の名前です。

データ型の設定

このフォームは、テーブルの列のタイプを変更します。列を含むインデックスと単純なテーブル制約は、最初に提供された式を再解析することにより、新しい列の型を使用するように自動的に変換されます。オプションの COLLATE 句は、新しい列の照合を指定します。省略した場合、照合は新しい列タイプのデフォルトになります。オプションの USING 句は、古い列の値から新しい列の値を計算する方法を指定します。省略した場合、デフォルトの変換は、古いデータ型から新しいデータ型への代入キャストと同じです。古い型から新しい型への暗黙的なキャストまたは代入キャストがない場合は、USING 句を指定する必要があります。

ALTER TABLEのドキュメントを参照してください。

于 2012-11-19T23:02:35.683 に答える
5

Ondrej が言うように、使用できますALTER TABLE .. ALTER COLUMN ... TYPE INTEGER

ただし、これによりテーブル全体の再書き込みがトリガーされ、その期間中のすべての同時書き込みまたは読み取りに対してテーブルがロックされます。大きなテーブルの場合、これには時間がかかる場合があります。

それを避ける必要がある場合は、段階的に変更できます。

  • BEGIN、新しい整数列を追加しますCOMMIT
  • BEGINトランザクションとLOCK TABLE ... IN EXCLUSIVE MODE同時挿入をブロックします。
  • UPDATEテーブル、smallintデータをinteger列にコピーします。
  • ここで列を削除し、smallint列の名前を の名前に変更しintegerます。smallintCOMMIT

またはの列から列に値をコピーするトリガーを作成する場合は、 を回避してLOCK TABLE同時書き込みを許可することもできます。新しい整数列を作成するのと同じトランザクション内にこのトリガーを追加して、 big と同時に追加された行をキャッチする必要があります。アプリケーションに対する変更の影響をさらに軽減するために、個々のトランザクションで小さなバッチで行を更新できるため、長い行レベルのロックを回避できます。BEFORE INSERT OR UPDATE ON ... FOR EACH ROWsmallintintegerINSERTUPDATEUPDATE

これについては、以前の dba.SE answer で詳しく説明しました

于 2012-11-20T00:20:06.077 に答える