PostgreSQL 8.4.1文書
前のページ | 巻戻し |  | 早送り | 次のページ

# ALTER TABLE

## 名前

ALTER TABLE -- テーブル定義を変更する

## 概要

    ALTER TABLE [ ONLY ] name [ * ]
        action [, ... ]
    ALTER TABLE [ ONLY ] name [ * ]
        RENAME [ COLUMN ] column TO new_column
    ALTER TABLE name
        RENAME TO new_name
    ALTER TABLE name
        SET SCHEMA new_schema

    ここで、actionは以下のいずれかです。

        ADD [ COLUMN ] column type [ column_constraint [ ... ] ]
        DROP [ COLUMN ] column [ RESTRICT | CASCADE ]
        ALTER [ COLUMN ] column [ SET DATA ] TYPE type [ USING expression ]
        ALTER [ COLUMN ] column SET DEFAULT expression
        ALTER [ COLUMN ] column DROP DEFAULT
        ALTER [ COLUMN ] column { SET | DROP } NOT NULL
        ALTER [ COLUMN ] column SET STATISTICS integer
        ALTER [ COLUMN ] column SET STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN }
        ADD table_constraint
        DROP CONSTRAINT constraint_name [ RESTRICT | CASCADE ]
        DISABLE TRIGGER [ trigger_name | ALL | USER ]
        ENABLE TRIGGER [ trigger_name | ALL | USER ]
        ENABLE REPLICA TRIGGER trigger_name
        ENABLE ALWAYS TRIGGER trigger_name
        DISABLE RULE rewrite_rule_name
        ENABLE RULE rewrite_rule_name
        ENABLE REPLICA RULE rewrite_rule_name
        ENABLE ALWAYS RULE rewrite_rule_name
        CLUSTER ON index_name
        SET WITHOUT CLUSTER
        SET WITH OIDS
        SET WITHOUT OIDS
        SET ( storage_parameter = value [, ... ] )
        RESET ( storage_parameter [, ... ] )
        INHERIT parent_table
        NO INHERIT parent_table
        OWNER TO new_owner
        SET TABLESPACE new_tablespace

## 説明

`ALTER TABLE`は既存のテーブルの定義を変更します。 このコマンドには、次のような副構文があります。

`ADD COLUMN`

  この構文を使用すると、CREATE TABLEと同じ構文を使って新しい列をテーブルに追加できます。

`DROP COLUMN`

  この構文を使用すると、テーブルから列を削除できます。 削除する列を含んでいるインデックスおよびテーブル制約も自動的に削除されます。 また、削除する列にテーブル以外（例えば、外部キー制約、ビューなど）が依存している場合、`CASCADE`を付ける必要があります。

`SET DATA TYPE`

  この構文を使用すると、テーブルの列の型を変更できます。 その列を含むインデックスと簡単なテーブル制約は、元々与えられた式を再解析し、新しい型を使用するように自動的に変換されます。 `USING`句は、古い列値をどのように新しい値に計算するかを指定します。この句は省略可能です。 省略された場合、デフォルトの変換は、古いデータ型から新しいデータ型への代入キャストと同じになります。 古いデータ型から新しいデータ型への暗黙キャストあるいは代入キャストがない場合、`USING`句を指定しなければなりません。

`SET`/`DROP DEFAULT`

  これらの構文を使用すると、列のデフォルト値を設定または削除できます。 指定したデフォルト値は、変更後に行われる`INSERT`コマンドのみに適用されます。 テーブル内の既存の行は変更されません。 デフォルト値はビューに対して設定することも可能です。 この場合、ビューの`ON INSERT`ルールが適用される前に、ビューの`INSERT`文にデフォルトが挿入されます。

`SET`/`DROP NOT NULL`

  これらの構文は、列の値としてNULL値を使用できるかどうか設定します。 `SET NOT NULL`は、その列にNULL値が1つもない場合にのみ設定可能です。

`SET STATISTICS`

  この構文は、コマンド実行後に行なわれるANALYZE操作において、列単位での統計情報収集対象を設定します。 対象として、0から10000までの範囲の値を設定可能です。 対象を-1に設定すると、システムのデフォルト統計情報対象（default_statistics_target）が使用されます。 PostgreSQLの問い合わせプランナによる統計情報の使用に関する詳細は、項14.2を参照してください。

`SET STORAGE`

  この構文は、列の保管モードを設定します。 列をインラインで保持するか補足テーブルに保持するか、また、データを圧縮するかどうかを制御できます。 `PLAIN`は、`integer`のような固定長の値に対して使用します。インラインで保持され、圧縮されません。 `MAIN`は、インラインで保持されていて、圧縮可能なデータに使用します。 `EXTERNAL`は圧縮されていない外部データに使用します。 `EXTENDED`は圧縮された外部データに使用します。 `EXTENDED`は、`PLAIN`以外の保管をサポートするほとんどのデータ型におけるデフォルトです。 `EXTERNAL`を使用すると、`text`および`bytea`列に対する部分文字列操作の処理速度が向上しますが、必要な保管容量が増えるというデメリットがあります。 `SET STORAGE`自体はテーブルをまったく変更しないことに注意してください。 以後のテーブルの更新時に遂行する戦略を設定するだけです。 詳細は項53.2を参照してください。

`ADD `table_constraint``

  この構文を使用すると、CREATE TABLEと同じ構文を使って新しい制約をテーブルに追加できます。

`DROP CONSTRAINT`

  この構文を使用すると、テーブル上の指定した制約を削除できます。

`DISABLE`/`ENABLE [ REPLICA | ALWAYS ] TRIGGER`

  この構文を使用すると、テーブルに属するトリガの発行について設定することができます。 無効にされたトリガはシステム上に存在し続けますが、トリガイベントが発生したとしても実行されません。 遅延トリガの場合、有効無効状態の確認は、トリガ関数を実際に実行しようとする時ではなく、イベントの発生時に行われます。 名前でトリガを1つ指定して有効または無効にすることもできますし、テーブル上のすべてのトリガを指定することもできます。 また、ユーザトリガのみを指定することも可能です（このオプションは外部キー制約を実装するために使用されるトリガを除外します）。 制約用のトリガを有効または無効にするにはスーパーユーザ権限が必要です。 トリガが実行されなかった場合に当然ながら制約の整合性が保証されませんので、注意して実行しなければなりません。 また、トリガ発行機構はsession_replication_role設定変数の影響を受けます。 単に有効としたトリガでは、リプリケーションロールが"オリジン"（デフォルト）または"ローカル"の場合に発行されます。 `ENABLE REPLICA`としたトリガでは、セッションが"リプリカ"モードである場合のみ発行されます。 そして、`ENABLE ALWAYS`としたトリガでは、現在のリプリケーションモードに関係なく発行されます。

`DISABLE`/`ENABLE [ REPLICA | ALWAYS ] RULE`

  この構文を使用すると、テーブルに属する書き換えルールの実行について設定することができます。 ルールは無効にしてもシステムに残りますが、問い合わせ書き換え時に適用されません。 この意味はトリガの有効化、無効化と同じです。 この設定は`ON SELECT`ルールでは無視されます。 現在のセッションがデフォルト以外のリプリケーションモードであったとしても、ビュー操作を維持するために常に適用されます。

`CLUSTER`

  この構文は、以後のCLUSTER操作用のデフォルトインデックスを選択します。 実際のテーブルの再クラスタ化は行いません。

`SET WITHOUT CLUSTER`

  この構文は、テーブルから、一番最後に適用されたCLUSTERインデックス指定を削除します。 以後のインデックスを指定しないクラスタ操作に影響を及ぼします。

`SET WITH OIDS`

  この構文は`oid`システム列をテーブルに追加します（項5.4を参照してください）。 テーブルがすでにOIDを持つ場合は何も行いません。

  これが、システム列ではなく`oid`という名前が付いただけの通常の列を追加する`ADD COLUMN oid oid`と同じではないことに注意してください。

`SET WITHOUT OIDS`

  この構文は、テーブルから`oid`システム列を削除します。 既に`oid`列が存在しなくても警告が表示されない点を除けば、`DROP COLUMN oid RESTRICT`とまったく同等です。

`SET ( `storage_parameter` = `value` [, ... ] )`

  この構文は、1つ以上のテーブルの格納パラメータを変更します。 設定可能なパラメータに関しては格納パラメータを参照してください。 このコマンドによってテーブルの内容が即座に変更されない点に注意してください。 パラメータによりますが、予定の効果を得るためにテーブルを書き換える必要がある場合があります。 このためには、テーブルを強制的に書き換えるCLUSTERまたは`ALTER TABLE`の構文のいずれかを使用してください。

  > 注意: `CREATE TABLE`では`OIDS`を`WITH (`storage_parameter`)`構文で指定することができますが、`ALTER TABLE`では`OIDS`を格納パラメータとして扱っていません。 OIDの状態を変更するためには代わりに`SET WITH OIDS`および`SET WITHOUT OIDS`構文を使用してください。

`RESET ( `storage_parameter` [, ... ] )`

  この構文は、1つ以上の格納パラメターをデフォルト値に再設定します。 `SET`同様、テーブル全体を更新するためにテーブルの書き換えが必要になる場合があります。

`INHERIT `parent_table``

  この構文は、対象テーブルを指定した親テーブルの子テーブルとして追加します。 その後に行われる親テーブルへの問い合わせには対象テーブルの項目も含まれます。 子テーブルとして追加するためには、対象テーブルには親テーブルと同じ列がすべて含まれていなければなりません。 （この他の列を持つこともできます。） これらの列のデータ型は一致している必要があり、親テーブルで`NOT NULL`制約がある場合は、子テーブルでも同様に`NOT NULL`制約を持たなければなりません。

  また、親テーブルの`CHECK`制約すべてについても、一致する制約が子テーブルに存在しなければなりません。 現時点では`UNIQUE`、`PRIMARY KEY`、`FOREIGN KEY`制約は無視されますが、将来変更されるかもしれません。

`NO INHERIT `parent_table``

  この構文は、指定した親テーブルから子テーブル群を削除します。 親テーブルへの問い合わせでは、対象としたテーブルからのデータが含まれなくなります。

`OWNER`

  この形式を使用すると、テーブル、シーケンス、またはビューの所有者を、指定したユーザに変更できます。

`SET TABLESPACE`

  この構文を使用すると、テーブルのテーブル空間を指定したテーブル空間に変更し、テーブルに関連するデータファイルを新しいテーブル空間に移動することができます。 テーブルにインデックスがあっても移動されません。 インデックスを移動するには、別途`SET TABLESPACE`コマンドを実行します。 CREATE TABLESPACEも参照してください。

`RENAME`

  `RENAME`構文を使用すると、テーブル（もしくは、インデックス、シーケンス、ビュー）の名前や、テーブルの個々の列名を変更できます。 格納されているデータへの影響はありません。

`SET SCHEMA`

  この構文を使用して、テーブルを別のスキーマに移動することができます。 関連するインデックスや制約、テーブル列により所有されるシーケンスも同様に移動されます。

`RENAME`および`SET SCHEMA`以外の全ての操作は、結合して複数の変更リストにまとめて、並行に処理することができます。 例えば、複数の列の追加、型の変更を単一のコマンドで実行することができます。 これは特に巨大なテーブルでは便利です。変更のために必要なテーブル全体の走査が1回で済むからです。

`ALTER TABLE`コマンドを使用するには、変更するテーブルを所有している必要があります。 テーブルのスキーマを変更するには、新しいスキーマにおける`CREATE`権限も持たなければなりません。 親テーブルに新しい子テーブルを追加するには、親テーブルも同様に所有している必要があります。 また、所有者を変更するには、新しい所有ロールの直接あるいは間接的なメンバでなければならず、かつ、そのロールがテーブルのスキーマにおける`CREATE`権限を持たなければなりません （この制限により強制的に所有者の変更が、テーブルの削除と再作成を行ってもできないことを行わないようにします。 ただし、スーパーユーザはすべてのテーブルの所有者を変更することができます）。

## パラメータ

`name`

  変更対象となる既存のテーブルの名前です（スキーマ修飾名も可）。 `ONLY`が指定された場合、そのテーブルのみが変更されます。 `ONLY`が指定されていない場合、そのテーブルおよびそのテーブルを継承する全てのテーブルが更新されます。

`column`

  新規または既存の列の名前です。

`new_column`

  既存の列の新しい名前です。

`new_name`

  テーブルの新しい名前です。

`type`

  新しい列のデータ型、もしくは既存の列に対する新しいデータ型です。

`table_constraint`

  テーブルの新しいテーブル制約です。

`constraint_name`

  削除する既存の制約の名前です。

`CASCADE`

  削除された列や制約に依存しているオブジェクト（例えば、削除された列を参照しているビューなど）を、自動的に削除します。

`RESTRICT`

  依存しているオブジェクトがある場合、列または制約の削除要求を拒否します。 これがデフォルトの動作です。

`trigger_name`

  有効または無効にする単一のトリガの名前です。

`ALL`

  テーブルに属するすべてのトリガを有効または無効にします。 （外部キー制約用のトリガが含まれる場合、スーパーユーザ権限が必要です。）

`USER`

  外部キー制約用のトリガ以外のテーブルに属するトリガすべてを有効または無効にします。

`index_name`

  指定したインデックス名でテーブルをクラスタ化するように印を付けます。

`storage_parameter`

  テーブルの格納パラメータの名前です。

`value`

  テーブルの格納パラメータの新しい値です。 パラメータによりこれは数値となることも文字列となることもあります。

`parent_table`

  このテーブルに関連付ける、または、このテーブルから関連付けを取り除く親テーブルです。

`new_owner`

  テーブルの新しい所有者のユーザ名です。

`new_tablespace`

  テーブルを移動する先のテーブル空間の名前です。

`new_schema`

  テーブルを移動する先のスキーマの名前です。

## 注釈

`COLUMN`キーワードはノイズであり、省略可能です。

`ADD COLUMN`によって列を追加した時、テーブル内の既存行に追加された列は、全てデフォルト値（`DEFAULT`が指定されていない場合はNULL）で初期化されます。

NULLではないデフォルト値を持つ列を追加したり、既存の列の型を変更するには、テーブル全体の書き換えが必要になります。 テーブルが巨大な場合、この処理に非常に時間がかかる可能性があります。また、一時的に2倍のディスク容量が必要とされます。 システム`oid`列の追加や削除も同様にテーブル全体の書き換えが必要です。

`CHECK`あるいは`NOT NULL`制約を追加する時は、既存の行が制約に従うかどうかを検証するためにテーブルの走査が必要になります。

単一の`ALTER TABLE`内に複数の変更を指定できるオプションを提供する主な理由は、複数のテーブル走査や書き換えを1回のテーブル走査にまとめることができるようにすることです。

`DROP COLUMN`構文は、列を物理的には削除せず、SQLを操作する上で不可視にします。 このコマンドを実行した後、テーブルに挿入または更新が行われると、削除した列にはNULLが格納されます。 したがって、列の削除は短時間で行えます。 しかし、削除された列が占めていた領域がまだ回収されていないため、テーブルのディスク上のサイズはすぐには小さくなりません。 この領域は、その後既存の行が更新されるタイミングで回収されます。 （システム`oid`列を削除する場合はこれらの文は適用されません。 これは即座の書き換えが行われます。）

`ALTER TYPE`がテーブル全体の書き換えを必要とすることが利点になる場合もあります。 書き換え処理によって、テーブル内の不要となった領域が除去されるからです。 例えば、削除した列が使用していた領域を即座に回収したい場合、最も高速なコマンドは次のようになります。

    ALTER TABLE table ALTER COLUMN anycol TYPE anytype;

ここで`anycol`には既存のテーブル列を、`anytype`には既存の列と同一の型を指定します。 このコマンドを実行すると、見た目にはテーブルに有意な変更はありませんが、不要となったデータを取り除く強制的な書き換えが行われます。

`ALTER TYPE`の`USING`オプションでは、その行の古い値を含め、どのような式でも指定できます。 つまり、変換対象の列と同様に、その他の列も参照することができます。 そのため、一般的な変換を`ALTER TYPE`構文で行うことができます。 この柔軟性のため、`USING`式は列のデフォルト値には（仮に存在していても）適用されません。 結果が定数式にならない可能性があるためです（デフォルト値は定数式でなければいけません）。 したがって、古い型から新しい型への暗黙キャストや代入キャストが存在しない場合、`USING`が指定されていても、`ALTER TYPE`がデフォルト値の変換に失敗する可能性があります。 この場合は、`DROP DEFAULT`でデフォルト値を削除し、`ALTER TYPE`を実行した後で、`SET DEFAULT`を使用して再度適切なデフォルト値を指定してください。 変更対象の列を持つインデックスと制約も同様の配慮が必要です。

そのテーブルを継承するテーブルがある場合、子テーブルに同じ処理を実行しなければ、親テーブルに対する列の追加、列の名前、型の変更を実行することはできません。 つまり、`ALTER TABLE ONLY`コマンドは受け付けられません。 この制限により、子テーブルの列が常に親テーブルと一致していることが保証されます。

再帰的な`DROP COLUMN`操作では、子テーブルが他の親テーブルからその列を継承しておらず、かつ、独立した列定義を持っていない場合のみ、その子テーブルの列を削除します。 再帰的でない`DROP COLUMN`（例えば、`ALTER TABLE ONLY ... DROP COLUMN`など）操作では、継承された列は削除されません。 削除する代わりに、その列は継承されておらず独立して定義されているという印を付けます。

`TRIGGER`、`CLUSTER`、`OWNER`および`TABLESPACE`は子テーブルに再帰的に伝わりません。 つまり、常に`ONLY`が指定されているかのように動作します。 制約の追加は、`CHECK`制約に関してのみ再帰的に伝わります。 こうした制約ではこのように動作することが求められています。

システムカタログテーブルについては、いかなる部分の変更も許可されていません。

有効なパラメータの詳しい説明はCREATE TABLEを参照してください。 第5章に、継承に関するさらに詳しい情報があります。

## 例

`varchar`型の列をテーブルに追加します。

    ALTER TABLE distributors ADD COLUMN address varchar(30);

テーブルから列を削除します。

    ALTER TABLE distributors DROP COLUMN address RESTRICT;

1つの操作で既存の2つの列の型を変更します。

    ALTER TABLE distributors
        ALTER COLUMN address TYPE varchar(80),
        ALTER COLUMN name TYPE varchar(100);

`USING`句を使用して、Unixタイムスタンプを持つinteger型の列を`timestamp with time zone`に変更します。

    ALTER TABLE foo
        ALTER COLUMN foo_timestamp SET DATA TYPE timestamp with time zone
        USING
            timestamp with time zone 'epoch' + foo_timestamp * interval '1 second';

上と同じです。 ただし、その列は、自動的に新しいデータ型にキャストされないデフォルト式を持ちます。

    ALTER TABLE foo
        ALTER COLUMN foo_timestamp DROP DEFAULT,
        ALTER COLUMN foo_timestamp TYPE timestamp with time zone
        USING
            timestamp with time zone 'epoch' + foo_timestamp * interval '1 second',
        ALTER COLUMN foo_timestamp SET DEFAULT now();

既存の列の名前を変更します。

    ALTER TABLE distributors RENAME COLUMN address TO city;

既存のテーブルの名前を変更します。

    ALTER TABLE distributors RENAME TO suppliers;

列に非NULL制約を付与します。

    ALTER TABLE distributors ALTER COLUMN street SET NOT NULL;

列から非NULL制約を削除します。

    ALTER TABLE distributors ALTER COLUMN street DROP NOT NULL;

テーブルとその子テーブルすべてにCHECK制約を付与します。

    ALTER TABLE distributors ADD CONSTRAINT zipchk CHECK (char_length(zipcode) = 5);

テーブルとその子テーブルからCHECK制約を削除します。

    ALTER TABLE distributors DROP CONSTRAINT zipchk;

1つのテーブルのみからCHECK制約を削除します。

    ALTER TABLE ONLY distributors DROP CONSTRAINT zipchk;

（このCHECK制約はすべての子テーブルで残ったままです。）

テーブルに外部キー制約を付与します。

    ALTER TABLE distributors ADD CONSTRAINT distfk FOREIGN KEY (address) REFERENCES addresses (address) MATCH FULL;

テーブルに（複数列の）一意性制約を付与します。

    ALTER TABLE distributors ADD CONSTRAINT dist_id_zipcode_key UNIQUE (dist_id, zipcode);

自動的に命名されるプライマリキー制約をテーブルに付与します。 1つのテーブルが持てるプライマリキーは1つだけであることに注意してください。

    ALTER TABLE distributors ADD PRIMARY KEY (dist_id);

テーブルを別のテーブル空間に移動します。

    ALTER TABLE distributors SET TABLESPACE fasttablespace;

テーブルを別のスキーマに移動します。

    ALTER TABLE myschema.distributors SET SCHEMA yourschema;

## 互換性

`ADD`、`DROP`、`SET DEFAULT`、`SET DATA TYPE`（`USING`がない）構文は標準SQLに従います。 他の構文は標準SQLに対するPostgreSQLの拡張です。 また、単一の`ALTER TABLE`コマンド内に複数の操作を指定する機能もPostgreSQLの拡張です。

`ALTER TABLE DROP COLUMN`を使って、1つしか列がないテーブルから列を削除して、列がないテーブルを作成することができます。 これはPostgreSQLの拡張です。SQLでは、列を持たないテーブルは認められていません。

前のページ | ホーム | 次のページ
ALTER SERVER | 上に戻る | ALTER TABLESPACE