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

# CREATE TABLE

## 名前

CREATE TABLE -- 新しいテーブルを定義する

## 概要

    CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXISTS ] table_name ( [
      { column_name data_type [ COLLATE collation ] [ column_constraint [ ... ] ]
        | table_constraint
        | LIKE parent_table [ like_option ... ] }
        [, ... ]
    ] )
    [ INHERITS ( parent_table [, ... ] ) ]
    [ WITH ( storage_parameter [= value] [, ... ] ) | WITH OIDS | WITHOUT OIDS ]
    [ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]
    [ TABLESPACE tablespace ]

    CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXISTS ] table_name
        OF type_name [ (
      { column_name WITH OPTIONS [ column_constraint [ ... ] ]
        | table_constraint }
        [, ... ]
    ) ]
    [ WITH ( storage_parameter [= value] [, ... ] ) | WITH OIDS | WITHOUT OIDS ]
    [ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]
    [ TABLESPACE tablespace ]

    column_constraintには、次の構文が入ります。

    [ CONSTRAINT constraint_name ]
    { NOT NULL |
      NULL |
      CHECK ( expression ) |
      DEFAULT default_expr |
      UNIQUE index_parameters |
      PRIMARY KEY index_parameters |
      REFERENCES reftable [ ( refcolumn ) ] [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ]
        [ ON DELETE action ] [ ON UPDATE action ] }
    [ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]

    また、table_constraintには、次の構文が入ります。

    [ CONSTRAINT constraint_name ]
    { CHECK ( expression ) |
      UNIQUE ( column_name [, ... ] ) index_parameters |
      PRIMARY KEY ( column_name [, ... ] ) index_parameters |
      EXCLUDE [ USING index_method ] ( exclude_element WITH operator [, ... ] ) index_parameters [ WHERE ( predicate ) ] |
      FOREIGN KEY ( column_name [, ... ] ) REFERENCES reftable [ ( refcolumn [, ... ] ) ]
        [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE action ] [ ON UPDATE action ] }
    [ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]

    and like_option is:

    { INCLUDING | EXCLUDING } { DEFAULTS | CONSTRAINTS | INDEXES | STORAGE | COMMENTS | ALL }

    UNIQUE、PRIMARY KEYおよびEXCLUDE制約内のindex_parametersは以下の通りです。

    [ WITH ( storage_parameter [= value] [, ... ] ) ]
    [ USING INDEX TABLESPACE tablespace ]
    EXCLUDE制約内のexclude_elementは以下の通りです。
    { column | ( expression ) } [ opclass ] [ ASC | DESC ] [ NULLS { FIRST | LAST } ]

## 説明

`CREATE TABLE`は、現在のデータベースに新しい空のテーブルを作成します。 作成したテーブルはこのコマンドを実行したユーザが所有します。

スキーマ名が付けられている場合（例えば、`CREATE TABLE myschema.mytable ...`）、テーブルは指定されたスキーマで作成されます。 スキーマ名がなければ、テーブルは現在のスキーマで作成されます。 また、一時テーブルは特別なスキーマに存在するため、一時テーブルの作成時にスキーマ名を与えることはできません。 テーブル名は、同じスキーマ内の他のテーブル、シーケンス、インデックス、ビュー、外部テーブルとは異なる名前にする必要があります。

さらに、`CREATE TABLE`は、作成するテーブルの1行に対応する複合型のデータ型を作成します。 したがって、テーブルは、同じスキーマ内の既存のデータ型と同じ名前を持つことができません。

制約句には、挿入、更新操作を行うために、新しい行、または更新する行が満たさなければならない制約（検査項目）を指定します。制約句は省略可能です。 制約は、テーブル内で様々な有効な値の集合を定義する際、役に立つSQLオブジェクトです。

制約の定義にはテーブル制約と列制約という2種類があります。 列制約は列定義の一部として定義されます。 テーブル制約定義は、特定の列とは結びつけられておらず、複数の列を含有することができます。 また、全ての列制約はテーブル制約として記述することができます。 列制約は、1つの列にのみ影響する制約のための、簡便な記述方法に過ぎません。

## パラメータ

`TEMPORARY` or `TEMP`

  このパラメータが指定された場合、テーブルは一時テーブルとして作成されます。 一時テーブルは、そのセッションの終わり、場合によっては、現在のトランザクションの終わり（後述の`ON COMMIT`を参照）に自動的に削除されます。 一時テーブルが存在する場合、同じ名前を持つ既存の永続テーブルは、スキーマ修飾名で参照されていない限り、現在のセッションでは非可視になります。 一時テーブルで作られるインデックスも、全て自動的に一時的なものとなります。

  autovacuum daemonは一時テーブルにアクセスできません。 したがって一時テーブルのバキュームや解析を行うことはできません。 このためセッションのSQLコマンドを用いて適切なバキュームと解析を実行しなければなりません。 例えば、一時テーブルが複雑な問い合わせで使用される場合、一時テーブルにデータを投入した後にそれに対し`ANALYZE`を実行することを勧めます。

  `GLOBAL`または`LOCAL`を`TEMPORARY`や`TEMP`の前に記述することができます（省略可能）。 PostgreSQLでは、これらを指定しても動作の違いはありません。 互換性を参照してください。

`UNLOGGED`

  指定された場合、テーブルはログを取らないテーブルとして作成されます。 ログを取らないテーブルに書き出されたデータは先行書き込みログ（第29章参照）には書き出されません。 このため通常のテーブルより相当高速になります。 しかしこれらはクラッシュ時に安全ではありません。 クラッシュまたは異常停止の後、ログを取らないテーブルは自動的に切り詰められます。 またログを取らないテーブルの内容はスタンバイサーバに複製されません。 ログを取らないテーブル上に作成されたインデックスはすべて同様に、ログを取らないようになります。 しかし現在ログをとらないGiST indexesはサポートされませんので、ログを取らないテーブル上に作成することはできません。

`IF NOT EXISTS`

  同じ名前のリレーションがすでに存在していてもエラーとしません。 この場合注意が発せられます。 既存のリレーションが作成しようとしたものと何かしら似たものであることは保証されません。

`table_name`

  作成するテーブルの名前です（スキーマ修飾名でも可）。

`OF `type_name``

  指定(スキーマ修飾可能)した複合型から構造を取り出した型付きテーブルを作成します。 型付きテーブルはその型に束縛されます。 例えば、型が(`DROP TYPE ... CASCADE`付きで)削除されるとそのテーブルは削除されます。

  型付きテーブルが作成されると、その列のデータ型は背後の複合型により決定され、`CREATE TABLE`コマンドでは指定されません。 しかし`CREATE TABLE`コマンドではテーブルにデフォルトと制約を追加できます。 また、格納パラメータの指定も可能です。

`column_name`

  新しいテーブルで作成される列の名前です。

`data_type`

  列のデータ型です。 これには、配列指定子を含めることができます。 PostgreSQLでサポートされるデータ型の情報に関する詳細は第8章を参照してください。

`COLLATE `collation``

  `COLLATE`句は列（照合順の設定が可能なデータ型でなければなりません）に照合順を割り当てます。 指定がなければ、列のデータ型のデフォルトの照合順が使用されます。

`INHERITS ( `parent_table` [, ... ] )`

  `INHERITS`句でテーブルの一覧を指定すると、新しいテーブルは指定されたテーブルの全ての列を自動的に継承します。この句は省略可能です。

  `INHERITS`を使用すると、新しい子テーブルとその親テーブル（複数可）との間に永続的な関連が作成されます。 通常、親へのスキーマ修飾子は同様に子にも伝播します。また、デフォルトでは、親テーブルの走査結果には子テーブルのデータが含まれます。

  複数の親テーブルに同一名の列が存在する場合、それらのデータ型が一致していなければ、エラーとして報告されます。 競合がなければ、これらの重複した列は新しいテーブルで1つの列の形に融合されます。 新しいテーブルの列名の一覧に継承する列の名前が含まれる場合も、そのデータ型は継承する列のデータ型と一致していなければなりません。さらに、その列定義は1つに融合されます。 新しいテーブルで明示的に列のデフォルト値を指定した場合、継承した列宣言における全てのデフォルト値は上書きされます。 デフォルト値を指定しなかった場合、親側でデフォルト値が指定されている時は、それらのデフォルト値が全て同じ値でなければなりません。 値が違う場合はエラーになります。

  `CHECK`制約は、基本的には列と同様の方法でマージされます。 複数の親テーブル、新しいテーブル、またはその両方の定義に同じ名前の`CHECK`制約が存在した場合、これらの制約はすべて同じ検査式を持たなければなりません。 さもなくば、エラーが報告されます。 同じ名前と式を持つ制約は１つのコピーにまとめられます。 一意な名前が常に選択されますので、新しいテーブル内の無名の`CHECK`制約はマージされないことに注意してください。

  列の`STORAGE`設定もまた親テーブルからコピーされます。

`LIKE `parent_table` [ `like_option` ... ]`

  `LIKE`句にテーブルを指定すると、自動的にそのテーブルの全ての列名、そのデータ型、非NULL制約が新しいテーブルにコピーされます。

  `INHERITS`との違いは、作成した後、新しいテーブルと元のテーブルが完全に分離されることです。 元のテーブルへの変更は新しいテーブルには適用されません。また、元のテーブルを操作しても新しいテーブルのデータは見つかりません。

  コピーする列のデフォルト式は、`INCLUDING DEFAULTS`が指定された場合にのみコピーされます。 デフォルトでは、デフォルト式がコピーされないため、新しいテーブルのコピーされた列はデフォルト値としてNULLを持つことになります。

  非NULL制約は常に新しいテーブルにコピーされます。 `CHECK`制約は、`INCLUDING CONSTRAINTS`が指定された場合にのみコピーされます。 他の種類の制約は決してコピーされません。 また、列制約とテーブル制約とを区別しません。 制約が要求される場合は、すべての検査制約がコピーされます。

  `INCLUDING INDEXES`句を指定しない限り、元のテーブル上のインデックスはまったく新しいテーブルには作成されません。

  複製された列定義に関する`STORAGE`設定は、`INCLUDING STORAGE`が指定された場合のみコピーされます。 このデフォルトの動作では、`STORAGE`設定は除外され、新しいテーブルにおけるコピーされた列は型固有のデフォルトの設定を持つようになります。 `STORAGE`の詳細については項55.2を参照してください。

  コピーされた列、制約、インデックスについてのコメントは`INCLUDING COMMENTS`が指定された場合のみコピーされます。 このデフォルトの動作では、コメントは除外され、新しいテーブルにおけるコピーされた列や制約はコメントを持ちません。

  `INCLUDING ALL`は`INCLUDING DEFAULTS INCLUDING CONSTRAINTS INCLUDING INDEXES INCLUDING STORAGE INCLUDING COMMENTS`の省略形です。

  また、`INHERITS`と異なり、`LIKE`によりコピーされた列や制約は類似の名前の列や制約にまとめられません。 同じ名前が明示的に、あるいは他の`LIKE`句で指定された場合、エラーが通知されます。

`CONSTRAINT `constraint_name``

  省略可能な列制約、テーブル制約の名前です。 もし、この制約に違反すると、制約名がエラーメッセージに含まれるようになります。 ですので、`col must be positive(正数でなければならない)`といった名前の制約名を付与することで、クライアントアプリケーションへ有用な制約情報を渡すことができます。 （空白を含む制約名を指定する場合、二重引用符が必要です。） 指定されなければ、システムが名前を生成します。

`NOT NULL`

  その列がNULL値を持てないことを指定します。

`NULL`

  その列がNULL値を持てることを指定します。 これがデフォルトです。

  この句は非標準的なSQLデータベースとの互換性のためだけに提供されています。 新しいアプリケーションでこれを使用するのはお勧めしません。

`CHECK ( `expression` )`

  `CHECK`は、論理型の結果を生成する、新しい行または更新される行が挿入または更新処理を成功させるために満足しなければならない式を指定します。 TRUEまたはUNKNOWNと評価される式は成功します。 挿入または更新処理の行がFALSEという結果をもたらす場合はエラー例外が発生し、その挿入または更新によるデータベースの変更は行われません。 列制約として指定された検査制約は列の値のみを参照しなければなりません。 テーブル制約内の式は複数の列を参照できます。

  現時点では、`CHECK`式には副問い合わせも現在の行の列以外の変数を含めることはできません。

`DEFAULT `default_expr``

  `DEFAULT`句を列定義に付けると、その列にデフォルトデータ値が割り当てられます。 値として指定するのは、任意の無変数式です（副問い合わせと現在のテーブル内の他の列へ交差参照は許可されません）。 デフォルト式のデータ型はその列のデータ型と一致する必要があります。

  デフォルト式は、全ての挿入操作において、その列に値が指定されていない場合に使用されます。 列にデフォルト値がない場合、デフォルト値はNULLになります。

`UNIQUE` （列制約）
`UNIQUE ( `column_name` [, ... ] )` （表制約）

  `UNIQUE`制約は、テーブルの1つまたは複数の列からなるグループが、一意な値のみを持つことができることを指定します。 一意性テーブル制約の動作は一意性列制約と同じですが、さらに複数列にまたがる機能を持ちます。

  一意性制約では、NULL値は等しいとはみなされなせん。

  それぞれの一意性テーブル制約には、そのテーブルの他の一意性制約もしくはプライマリキー制約によって名付けられた列の集合とは、異なる名前の列の集合を指定しなければなりません （同じ名前を指定すると、同じ制約が2回現れるだけになります）。

`PRIMARY KEY` （列制約）
`PRIMARY KEY ( `column_name` [, ... ] )` （表制約）

  プライマリキー制約は、テーブルの1列または複数列が一意な（重複がない）、非NULL値のみを持つことを指定します。 技術的には、`PRIMARY KEY`は単なる`UNIQUE`と`NOT NULL`の組み合わせです。 しかし、プライマリキーであることは他のテーブルがその列集合を一意な行識別子とみなせることを意味するので、列集合をプライマリキーと特定すると、スキーマ設計に関するメタデータを提供することになります。

  列制約であるかテーブル制約であるかにかかわらず、1つのテーブルに指定できるプライマリキーは1つだけです。

  プライマリキー制約には、そのテーブルに定義された他の一意性制約で指名された列の集合とは違う組み合わせの列の集合を指定しなければなりません。

`EXCLUDE [ USING `index_method` ] ( `exclude_element` WITH `operator` [, ... ] ) `index_parameters` [ WHERE ( `predicate` ) ]`

  `EXCLUDE`句は、任意の2行を指定した列(複数可)または式(複数可)を指定した演算子(複数可)を使用して比較した場合、比較結果のすべてが`TRUE`を返さないことを保障する、除外制約を定義します。 指定した演算子のすべてが等価性を試験するものであれば、これは`UNIQUE`制約と同じです。 しかし、通常の一意性制約のほうが高速です。 しかし、除外制約では単純な等価性よりも一般的な制約を指定することができます。 例えば、テーブル内の2つの行が重複しない円(項8.8参照)を持たないといった制約を`&&`演算子を使用して指定することができます。

  除外制約はインデックスを使用して実装されています。 このため指定した演算子はそれぞれ適切な演算子クラス(項11.9参照)で`index_method`インデックスアクセスメソッドと関連付けされていなければなりません。 演算子は交換可能でなければなりません。 省略可能ですが、各`exclude_element`は演算子クラス、順序付けオプション、またはその両方を指定することができます。 これらについてはCREATE INDEXで説明します。

  アクセスメソッドは`amgettuple`をサポートしなければなりません(第52章参照)。 現時点では、これはGINを使用できないことを意味します。 許されることですが、B-treeやHashインデックスを除外制約で使用する場合に少し問題があります。 これが通常の一意性制約がよりよく行わないことを行うためです。 このため現実的にはアクセスメソッドは常にGiSTとなります。

  `predicate`により、除外制約をテーブルの部分集合に指定することができます。 内部的には、これは部分インデックスを作成します。 述語の前後に括弧が必要であることに注意して下さい。

`REFERENCES `reftable` [ ( `refcolumn` ) ] [ MATCH `matchtype` ] [ ON DELETE `action` ] [ ON UPDATE `action` ]` （列制約）
`FOREIGN KEY ( `column` [, ... ] ) REFERENCES `reftable` [ ( `refcolumn` [, ... ] ) ] [ MATCH `matchtype` ] [ ON DELETE `action` ] [ ON UPDATE `action` ]` （表制約）

  これらの句は、外部キー制約を指定します。 外部キー制約は、新しいテーブルの1つまたは複数の列の集合が、被参照テーブルの一部の行の被参照列（複数可）に一致する値を持たなければならないことを指定するものです。 `refcolumn`が省略された場合、`reftable`のプライマリキーが使用されます。 被参照列は、被参照テーブルにおいて遅延不可の一意性制約もしくはプライマリキー制約を持った列でなければなりません。 一時テーブルと永続テーブルとの間で外部キー制約を定義できないことに注意してください。

  参照列に挿入された値は、被参照テーブルと被参照列の値に対して、指定した照合型で照会されます。 照合型には3種類があります。 `MATCH FULL`、`MATCH PARTIAL`、デフォルトでもある`MATCH SIMPLE`照合型です。 `MATCH FULL`は全ての外部キー列がNULLとなる場合を除き、複数列外部キーのある列がNULLとなることを許可しません。 `MATCH SIMPLE`照合型は、外部キーの他の部分がNULLでない限り、外部キーの一部をNULLとなることを許可します。 `MATCH PARTIAL`はまだ実装されていません。

  さらに、被参照列のデータが変更された場合、このテーブルの列のデータに何らかの動作が発生します。 `ON DELETE`句は、被参照テーブルの被参照行が削除された場合の動作を指定します。 同様に`ON UPDATE`句は、被参照テーブルの被参照列が新しい値に更新された場合の動作を指定します。 行の更新があった場合でも、被参照列が実際に変更されない場合は、動作は実行されません。 制約が遅延可能と宣言されていても、`NO ACTION`検査以外の参照動作は遅延させられません。 各句について、以下の動作を指定可能です。

  `NO ACTION`

    削除もしくは更新が外部キー制約違反となることを示すエラーを発生します。 制約が遅延可能な場合、何らかの参照行が存在する限り、このエラーは制約の検査時点で発生します。 これはデフォルトの動作です。

  `RESTRICT`

    削除もしくは更新が外部キー制約違反となることを示すエラーを発生します。 検査が遅延できない点を除き、`NO ACTION`と同じです。

  `CASCADE`

    削除された行を参照している行は全て削除します。また、参照している列の値を、被参照列の新しい値にします。

  `SET NULL`

    参照する列（複数可）をNULLに設定します。

  `SET DEFAULT`

    参照する列（複数可）をそのデフォルト値に設定します。

  被参照列が頻繁に更新される場合、外部キー列にインデックスを付け、その外部キー列に関連する参照動作がより効率的に実行できるようにする方が良いでしょう。

`DEFERRABLE`
`NOT DEFERRABLE`

  制約を遅延させることが可能かどうかを制御します。 遅延不可の制約は各コマンドの後すぐに検査されます。 遅延可能な制約の検査は、（SET CONSTRAINTSコマンドを使用して）トランザクションの終了時まで遅延させることができます。 `NOT DEFERRABLE`がデフォルトです。 現在、`UNIQUE`、`PRIMARY KEY`、`EXCLUDE`、`REFERENCES`（外部キー）制約のみがこの句を受け付けることができます。 `NOT NULL`および `CHECK`制約は遅延させることができません。

`INITIALLY IMMEDIATE`
`INITIALLY DEFERRED`

  制約が遅延可能な場合、この句は制約検査を行うデフォルトの時期を指定します。 制約が`INITIALLY IMMEDIATE`の場合、各文の実行後に検査されます。 これがデフォルトです。 制約が`INITIALLY DEFERRED`の場合、トランザクションの終了時にのみ検査されます。 制約検査の時期はSET CONSTRAINTSコマンドを使用して変更することができます。

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

  この句は、テーブルまたはインデックスに対して省略可能な格納パラメータを指定します。 詳細は格納パラメータを参照してください。 テーブル用の`WITH`には、`OIDS=TRUE`（もしくは単なる`OIDS`）を含めて、新しいテーブルの行が行に割り当てられたOID（オブジェクト識別子）を持たなければならないことを指定することもできます。 また、`OIDS=FALSE`を含めて、OIDを持たないことを指定することもできます。 `OIDS`が指定されない場合、デフォルトの設定はdefault_with_oids設定パラメータに依存します。 （新しいテーブルがOIDを持つテーブルから継承する場合、コマンドで`OIDS=FALSE`と指定しても強制的に`OIDS=TRUE` となります。）

  `OIDS=FALSE`が明示的または暗黙的に指定されている場合、新しいテーブルはOIDを格納しません。また、挿入される行にはOIDが割り当てられません。 このような動作は一般的に有益であると考えられます。それは、OIDの使用を抑え、32ビットのOIDカウンタの回転周期を延長できるためです。 カウンタが一周するとOIDの一意性を保証できなくなるので、その有用性を減少させることになります。 また、OIDをなくすことで、テーブル1行当たり（ほとんどのマシンで）4バイト分、テーブルをディスクに格納するための容量を軽減するので、多少性能が向上します。

  テーブルの作成後にOIDを削除するには、ALTER TABLEを使用してください。

`WITH OIDS`
`WITHOUT OIDS`

  これは古い構文で、それぞれ`WITH (OIDS)` and `WITH (OIDS=FALSE)`と同じです。 `OIDS`の設定と格納パラメータの設定の両方を指定したい場合は、上述の`WITH ( ... )`を使用しなければなりません。

`ON COMMIT`

  `ON COMMIT`を使用して、トランザクションブロックの終了時点での一時テーブルの動作を制御することができます。 以下の3つのオプションがあります。

  `PRESERVE ROWS`

    トランザクションの終了時点で、特別な動作は行われません。 これがデフォルトの動作です。

  `DELETE ROWS`

    一時テーブル内の全ての行は、各トランザクションブロックの終わりで削除されます。 基本的には、コミットの度に自動的にTRUNCATEが実行されます。

  `DROP`

    一時テーブルは、現在のトランザクションブロックの終了時点で削除されます。

`TABLESPACE `tablespace``

  `tablespace`は、新しいテーブルが作成されるテーブル空間名です。 指定されていない場合、default_tablespace、もし一時テーブルの場合はtemp_tablespacesが考慮されます。

`USING INDEX TABLESPACE `tablespace``

  この句により、`UNIQUE`、`PRIMARY KEY`、または`EXCLUDE`制約に関連したインデックスを作成するテーブル空間を選択することができます。 指定されていない場合、default_tablespace、もし一時テーブルであればtemp_tablespacesが考慮されます。

### 格納パラメータ

`WITH`句により、テーブルおよび`UNIQUE`、`PRIMARY KEY`、または`EXCLUDE`制約と関連づいたインデックスの格納パラメータを指定することができます。 インデックスの格納パラメータについてはCREATE INDEXで説明します。 現在テーブルで設定可能な格納パラメータの一覧を以下に示します。 各パラメータに対して、注記がない限り、さらに`toast`という接頭辞のついた、同一の名前のパラメータがあります。 これはもしあれば、テーブルの補助TOASTテーブルの動作を制御するために使用することができます。 (TOASTに関する詳細については項55.2を参照してください。) TOASTテーブルは、`toast.autovacuum_*`の設定群がない場合に親テーブルの`autovacuum`値を継承することに注意してください。

`fillfactor` (`integer`)

  テーブルのフィルファクタは10から100までの間の割合（パーセント）です。 100（完全にすべて使用）がデフォルトです。 より小さな値を指定すると、`INSERT`操作は指定した割合までしかテーブルページを使用しません。 各ページの残りの部分は、そのページ内の行更新用に予約されます。 これにより`UPDATE`は、元の行と同じページ上に更新済みの行の複製を格納することができるようになります。 これは別のページに更新済みの行の複製を格納することよりも効率的です。 項目の更新がまったくないテーブルでは、完全にすべてを使用することが最善の選択です。 しかし、更新が非常に多いテーブルではより小さめのフィルファクタが適切です。 TOASTテーブルではこのパラメータを設定できません。

`autovacuum_enabled`, `toast.autovacuum_enabled` (`boolean`)

  特定のテーブルに対する自動バキュームデーモンを有効または無効にします。 真の場合、自動バキュームデーモンは、更新または削除されたタプル数が`autovacuum_vacuum_threshold`＋`autovacuum_vacuum_scale_factor`×リレーション内の推定有効タプル数を超えたときに、特定のテーブルに対する`VACUUM`操作を始めます。 同様に、挿入、更新、削除されたタプル数が`autovacuum_analyze_threshold`＋`autovacuum_analyze_scale_factor`×リレーション内の推定有効タプル数を超えたときに、`ANALYZE`操作を始めます。 偽の場合、トランザクション周回問題を回避するため以外で自動バキュームは行われません。 周回問題の回避については項23.1.4を参照してください。 この変数がautovacuumからの値を継承していることに気付いてください。

`autovacuum_vacuum_threshold`, `toast.autovacuum_vacuum_threshold` (`integer`)

  特定のテーブルに対して`VACUUM`操作を始める前の、更新または削除されたタプルの最小数です。

`autovacuum_vacuum_scale_factor`, `toast.autovacuum_vacuum_scale_factor` (`float4`)

  `autovacuum_vacuum_threshold`に加算する`reltuples`用の乗数です。

`autovacuum_analyze_threshold` (`integer`)

  特定のテーブルに対して`ANALYZE`操作を始める前の、挿入、更新または削除されたタプルの最小数です。

`autovacuum_analyze_scale_factor` (`float4`)

  `autovacuum_analyze_threshold`に加算する`reltuples`用の乗数です。

`autovacuum_vacuum_cost_delay`, `toast.autovacuum_vacuum_cost_delay` (`integer`)

  autovacuum_vacuum_cost_delay独自パラメータです。

`autovacuum_vacuum_cost_limit`, `toast.autovacuum_vacuum_cost_limit` (`integer`)

  autovacuum_vacuum_cost_limit独自パラメータです。

`autovacuum_freeze_min_age`, `toast.autovacuum_freeze_min_age` (`integer`)

  vacuum_freeze_min_age独自パラメータです。 テーブル単位の`autovacuum_freeze_min_age`をシステム全体のautovacuum_freeze_max_age設定の1/2より大きく設定しようとしても、自動バキュームが無視することに注意してください。

`autovacuum_freeze_max_age`, `toast.autovacuum_freeze_max_age` (`integer`)

  autovacuum_freeze_max_age独自パラメータです。 テーブル単位の`autovacuum_freeze_max_age`をシステム全体のに対する設定より大きく設定しようとしても、自動バキュームが無視することに注意してください。 （より小さな値しか設定できません。） `autovacuum_freeze_max_age`を非常に小さく設定する、ゼロに設定することすらできますが、頻繁なバキューム処理が強制されるため通常は勧められません。

`autovacuum_freeze_table_age`, `toast.autovacuum_freeze_table_age` (`integer`)

  Custom vacuum_freeze_table_age parameter.

## 注釈

新規のアプリケーションでOIDを使用するのはお勧めしません。 できる限り、テーブルのプライマリキーとして`SERIAL`や他のシーケンスジェネレータを使用する方が望ましいと考えられます。 しかし、アプリケーションがテーブルの特定の行を識別するためにOIDを使用する場合は、そのテーブルの`oid`列に一意性制約を作成することを推奨します。 これにより、カウンタが一周してしまった場合でも、テーブル内のOIDで一意に行を識別できることが保証されるからです。 OIDがテーブル全体で一意であると考えるのは止めてください。 データベース全体で一意な識別子が必要な場合は、`tableoid`と行のOIDの組み合わせを使用してください。

> ティップ: `OIDS=FALSE`の使用は、プライマリキーのないテーブルでは推奨されません。 OIDも一意なデータキーも存在しないと、特定行を識別することが難しくなるからです。

PostgreSQLは自動的に各一意性制約とプライマリキー制約に対してインデックスを作成し、その一意性を確実なものにします。 したがって、プライマリキーの列に明示的なインデックスを作成することは必要ありません （詳細についてはCREATE INDEXを参照してください）。

現在の実装では、一意性制約とプライマリキーは継承されません。 これは、継承と一意性制約を組み合わせると障害が発生するからです。

テーブルは1600列以上の列を持つことはできません （タプル長の制限により実際の制限はもっと低くなります）。

## 例

`films`テーブルと`distributors`テーブルを作成します。

    CREATE TABLE films (
        code        char(5) CONSTRAINT firstkey PRIMARY KEY,
        title       varchar(40) NOT NULL,
        did         integer NOT NULL,
        date_prod   date,
        kind        varchar(10),
        len         interval hour to minute
    );

    CREATE TABLE distributors (
         did    integer PRIMARY KEY DEFAULT nextval('serial'),
         name   varchar(40) NOT NULL CHECK (name <> '')
    );

2次元配列を持つテーブルを作成します。

    CREATE TABLE array_int (
        vector  int[][]
    );

`films`テーブルに 一意性テーブル制約を定義します。 一意性テーブル制約はテーブルの1つ以上の列に定義することができます。

    CREATE TABLE films (
        code        char(5),
        title       varchar(40),
        did         integer,
        date_prod   date,
        kind        varchar(10),
        len         interval hour to minute,
        CONSTRAINT production UNIQUE(date_prod)
    );

検査列制約を定義します。

    CREATE TABLE distributors (
        did     integer CHECK (did > 100),
        name    varchar(40)
    );

検査テーブル制約を定義します。

    CREATE TABLE distributors (
        did     integer,
        name    varchar(40)
        CONSTRAINT con1 CHECK (did > 100 AND name <> '')
    );

`films`テーブルにプライマリキーテーブル制約を定義します。

    CREATE TABLE films (
        code        char(5),
        title       varchar(40),
        did         integer,
        date_prod   date,
        kind        varchar(10),
        len         interval hour to minute,
        CONSTRAINT code_title PRIMARY KEY(code,title)
    );

`distributors`テーブルにプライマリキー制約を定義します。 以下の2つの例は同じものです。 前者はテーブル制約構文を使用し、後者は列制約構文を使用します。

    CREATE TABLE distributors (
        did     integer,
        name    varchar(40),
        PRIMARY KEY(did)
    );

    CREATE TABLE distributors (
        did     integer PRIMARY KEY,
        name    varchar(40)
    );

以下では、`name`列のデフォルト値にリテラル定数を割り当てています。また、`did`列のデフォルト値として、シーケンスオブジェクトの次の値が生成されるように調整しています。 `modtime`のデフォルト値は、その行が挿入された時刻となります。

    CREATE TABLE distributors (
        name      varchar(40) DEFAULT 'Luso Films',
        did       integer DEFAULT nextval('distributors_serial'),
        modtime   timestamp DEFAULT current_timestamp
    );

2つの`NOT NULL`列制約を`distributors`テーブルに定義します。 そのうち1つには明示的な名前を付けています。

    CREATE TABLE distributors (
        did     integer CONSTRAINT no_null NOT NULL,
        name    varchar(40) NOT NULL
    );

`name`列に対し、一意性制約を定義します。

    CREATE TABLE distributors (
        did     integer,
        name    varchar(40) UNIQUE
    );

上をテーブル制約として指定します。

    CREATE TABLE distributors (
        did     integer,
        name    varchar(40),
        UNIQUE(name)
    );

テーブルとその一意性インデックスに70%のfillファクタを指定して、同じテーブルを作成します。

    CREATE TABLE distributors (
        did     integer,
        name    varchar(40),
        UNIQUE(name) WITH (fillfactor=70)
    )
    WITH (fillfactor=70);

2つの円の重複を許さない除外制約を持つ`circles`テーブルを作成します。

    CREATE TABLE circles (
        c circle,
        EXCLUDE USING gist (c WITH &&)
    );

`diskvol1`テーブル空間に`cinemas`テーブルを作成します。

    CREATE TABLE cinemas (
            id serial,
            name text,
            location text
    ) TABLESPACE diskvol1;

複合型と型付きテーブルを作成します。

    CREATE TYPE employee_type AS (name text, salary numeric);

    CREATE TABLE employees OF employee_type (
        PRIMARY KEY (name),
        salary WITH OPTIONS DEFAULT 1000
    );

## 互換性

`CREATE TABLE`は、以下の一覧を除いて、標準SQLに従います。

### 一時テーブル

`CREATE TEMPORARY TABLE`は標準SQLに類似していますが、その効果は同じではありません。 標準では、一時テーブルは一度だけ定義され、それを必要とするセッションごとに自動的に（空の内容で始まる形で）出現します。 PostgreSQLでは、これと異なり、各セッションで独自に、使用する一時テーブル用の`CREATE TEMPORARY TABLE`コマンドを発行しなければなりません。 これにより、異なるセッションで同じ名前の一時テーブルを異なる目的で使用することができます。 一方、標準の方法では、ある一時テーブル名を持つインスタンスが、全て同一のテーブル構造を持つという制限があります。

標準におけるこのような一時テーブルの動作定義はたいてい無視されています。 この点でのPostgreSQLの動作は、他の多くのSQLデータベースと似ています。

標準における、グローバル一時テーブルとローカル一時テーブルの区別はPostgreSQLにはありません。 この区別はモジュールという概念に依存したものですが、PostgreSQLにはモジュール概念がないからです。 互換性を保持するため、PostgreSQLは一時テーブルの宣言において`GLOBAL`と`LOCAL`キーワードを受け付けますが、これらには何の効果もありません。

一時テーブル用の`ON COMMIT`句もまた、標準SQLに類似していますが、数点の違いがあります。 `ON COMMIT`句が省略された場合、SQLでは、デフォルトの動作は`ON COMMIT DELETE ROWS`であると規定しています。 しかし、PostgreSQLでのデフォルトの動作は`ON COMMIT PRESERVE ROWS`です。 また、`ON COMMIT DROP`はSQLにはありません。

### 非遅延一意性制約

`UNIQUE`または`PRIMARY KEY`制約が非遅延の場合、PostgreSQLは行が挿入または変更されると即座に一意性を検査します。 標準SQLでは一意性は文が完了した時にのみ強制されなければならないと記述しています。 これにより、たとえば、1つのコマンドが複数のキー値を更新する時に違いが現れます。 標準互換の動作をさせるためには、非遅延（つまり`INITIALLY IMMEDIATE`）ではなく`DEFERRABLE`として制約を宣言してください。 これが即座に行われる一意性検査よりかなり低速になる可能性があることに注意してください。

### 列検査制約

標準SQLでは、`CHECK`列制約はそれを適用する列のみを参照でき、複数の列を参照できるのは`CHECK`テーブル制約のみであるとされています。 PostgreSQLにはこの制限はありません。 列検査制約とテーブル検査制約を同様のものとして扱っています。

### `EXCLUDE`制約

`EXCLUDE`という種類の制約はPostgreSQLの拡張です。

### `NULL` "制約"

`NULL`"制約"（実際には非制約）は、標準SQLに対するPostgreSQLの拡張で、他のいくつかのデータベースシステムとの互換性のために含まれています（`NOT NULL`制約と対称になります）。 どんな列に対してもデフォルトとなるため、これはノイズに過ぎません。

### 継承

`INHERITS`句による複数継承は、PostgreSQLの言語拡張です。 SQL:1999以降では、異なる構文と意味体系による単一継承を定義しています。 今のところ、SQL:1999方式の継承はPostgreSQLではサポートされていません。

### 列を持たないテーブル

PostgreSQLでは、列を持たないテーブルを作成することができます （例えば、`CREATE TABLE foo();`）。 これは標準SQLからの拡張です。 標準SQLでは列を持たないテーブルは許されません。 列を持たないテーブルそれ自体は役に立ちませんが、これを無効とすると、`ALTER TABLE DROP COLUMN`に対して奇妙な特例を生成することになります。 したがって、この仕様上の制限を無視する方が簡潔であると考えます。

### `WITH`句

`WITH`句はPostgreSQLの拡張です。 格納パラメータもOIDも標準にはありません。

### テーブル空間

PostgreSQLのテーブル空間の概念は標準にはありません。 したがって、`TABLESPACE`と`USING INDEX TABLESPACE`は、PostgreSQLにおける拡張です。

### 型付きテーブル

型付きテーブルは標準SQLのサブセットを実装します。 標準に従うと、型付きテーブルは背後の複合型に対応した列の他に"自己参照列"という列も持ちます。 PostgreSQLはこうした自己参照列を明示的にサポートしません。 しかし、OID機能を使用して同様の効果を持たせることができます。

## 関連項目

ALTER TABLE, DROP TABLE, CREATE TABLESPACE, CREATE TYPE

前のページ | ホーム | 次のページ
CREATE SERVER | 上に戻る | CREATE TABLE AS