[11/15開催: PostgreSQL Conference Japan 2019 参加受付中] 
他のバージョンの文書 11 | 10 | 9.6 | 9.5 | 9.4 | 9.3 | 9.2 | 9.1 | 9.0 | 8.4 | 8.3 | 8.2 | 8.1 | 8.0 | 7.4 | 7.3 | 7.2

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 source_table [ like_option ... ] }
    [, ... ]
] )
[ INHERITS ( parent_table [, ... ] ) ]
[ PARTITION BY { RANGE | LIST | HASH } ( { column_name | ( expression ) } [ COLLATE collation ] [ opclass ] [, ... ] ) ]
[ WITH ( storage_parameter [= value] [, ... ] ) | WITH OIDS | WITHOUT OIDS ]
[ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]
[ TABLESPACE tablespace_name ]

CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXISTS ] table_name
    OF type_name [ (
  { column_name [ WITH OPTIONS ] [ column_constraint [ ... ] ]
    | table_constraint }
    [, ... ]
) ]
[ PARTITION BY { RANGE | LIST | HASH } ( { column_name | ( expression ) } [ COLLATE collation ] [ opclass ] [, ... ] ) ]
[ WITH ( storage_parameter [= value] [, ... ] ) | WITH OIDS | WITHOUT OIDS ]
[ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]
[ TABLESPACE tablespace_name ]

CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXISTS ] table_name
    PARTITION OF parent_table [ (
  { column_name [ WITH OPTIONS ] [ column_constraint [ ... ] ]
    | table_constraint }
    [, ... ]
) ] { FOR VALUES partition_bound_spec | DEFAULT }
[ PARTITION BY { RANGE | LIST | HASH } ( { column_name | ( expression ) } [ COLLATE collation ] [ opclass ] [, ... ] ) ]
[ WITH ( storage_parameter [= value] [, ... ] ) | WITH OIDS | WITHOUT OIDS ]
[ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]
[ TABLESPACE tablespace_name ]


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

[ CONSTRAINT constraint_name ]
{ NOT NULL |
  NULL |
  CHECK ( expression ) [ NO INHERIT ] |
  DEFAULT default_expr |
  GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ( sequence_options ) ] |
  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 ) [ NO INHERIT ] |
  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 ]


またlike_optionは、以下の通りです。

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


またpartition_bound_specは、以下の通りです。

IN ( { numeric_literal | string_literal | TRUE | FALSE | NULL } [, ...] ) |
FROM ( { numeric_literal | string_literal | TRUE | FALSE | MINVALUE | MAXVALUE } [, ...] )
  TO ( { numeric_literal | string_literal | TRUE | FALSE | MINVALUE | MAXVALUE } [, ...] ) |
WITH ( MODULUS numeric_literal, REMAINDER numeric_literal )


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

[ INCLUDE ( column_name [, ... ] ) ]
[ WITH ( storage_parameter [= value] [, ... ] ) ]
[ USING INDEX TABLESPACE tablespace_name ]


EXCLUDE制約内のexclude_elementは以下の通りです。

{ column_name | ( expression ) } [ opclass ] [ ASC | DESC ] [ NULLS { FIRST | LAST } ]

説明

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

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

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

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

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

テーブルを作成するためには、すべての列の型またはOF句中の型に対するUSAGE権限を持たなければなりません。

パラメータ

TEMPORARYまたはTEMP

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

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

オプションで、GLOBALまたはLOCALTEMPORARYTEMPの前に記述することができます。 PostgreSQLでは、現在違いがなく、廃止予定です。 互換性を参照してください。

UNLOGGED

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

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制約が存在した場合、これらの制約はすべて同じ検査式を持たなければなりません。 さもなくば、エラーが報告されます。 同じ名前と式を持つ制約は1つのコピーにまとめられます。 親テーブルでNO INHERITと印が付いた制約は考慮されません。 新しいテーブル内の無名のCHECK制約は、一意な名前が必ず作られるため、マージされないことに注意してください。

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

親テーブルのある列がIDENTITY列の場合、その属性は継承されません。 望むなら子テーブルの列をIDENTY列と宣言することができます。

PARTITION BY { RANGE | LIST | HASH } ( { column_name | ( expression ) } [ opclass ] [, ...] )

オプションのPARTITION BY句により、テーブルのパーティショニングの戦略を指定できます。 このようにして作られたテーブルをパーティションテーブルと呼びます。 括弧に囲まれた列や式のリストはテーブルのパーティションキーを構成します。 範囲パーティションを使うときは、パーティションキーは複数の列または式にまたがることができます(最大で32ですが、この制限はPostgreSQLをビルドする時に変更できます)が、リストパーティションでは、パーティションキーは1つだけの列または式で構成されなければなりません。 パーティションテーブルの作成時にBツリー演算子クラスを指定しない場合は、そのデータ型のデフォルトのBツリー演算子クラスが使用されます。 Bツリー演算子クラスがない場合はエラーが報告されます。

Range and list partitioning require a btree operator class, while hash partitioning requires a hash operator class. If no operator class is specified explicitly, the default operator class of the appropriate type will be used; if no default operator class exists, an error will be raised. When hash partitioning is used, the operator class used must implement support function 2 (see 38.15.3 for details).

パーティションテーブルは(パーティションと呼ばれる)副テーブルに分割され、それらは別のCREATE TABLEコマンドにより作成されます。 パーティションテーブルそれ自体は空になります。 テーブルに挿入されるデータ行は、パーティションキーの列あるいは式の値に基づいて、1つのパーティションに回されます。 新しい行の値に適合するパーティションが存在しないときは、エラーが報告されます。

パーティションテーブルはUNIQUEPRIMARY KEYEXCLUDEFOREIGN KEYの各制約をサポートしませんが、個々のパーティションでこれらの制約を定義することはできます。

テーブルパーティショニングの更なる議論は5.10を参照してください。

PARTITION OF parent_table { FOR VALUES partition_bound_spec | DEFAULT }

指定した親テーブルのパーティションとしてテーブルを作成します。 FOR VALUESを用いて特定の値のパーティションとして、あるいは、DEFAULTを用いてデフォルトパーティションとしてテーブルを作成できます。 本オプションはハッシュパーティションされたテーブルには使用できません。

partition_bound_specは親テーブルのパーティショニング方法とパーティションキーに対応していなければならず、またそのテーブルのどの既存のパーティションとも重なり合ってはいけません。 INの構文はリストパーティショニングで、FROMTOの構文は範囲パーティショニングで、WITHの構文はハッシュパーティショニングで、使用されます。

partition_bound_specで指定される各値はリテラル、NULLMINVALUEあるいはMAXVALUEです。 各リテラル値はパーティションキー列の型に変換可能な数値定数か、その列の型として有効な入力である文字列リテラルのいずれかです。

リストパーティションを作るときは、NULLを指定することができて、それはそのパーティションではパーティションキーの列をNULLにすることができるということを意味します。 しかし、1つの親テーブルで2つ以上、そのようなリストパーティションを作ることはできません。 範囲パーティションではNULLを指定することはできません。

範囲パーティションを作るとき、FROMで指定する下限はそれを含む境界、TOで指定する上限はそれを含まない境界になります。 つまり、FROMリストで指定される値は、そのパーティションの対応するパーティションキー列において有効な値ですが、TOリストで指定される値はそうではない、ということです。 この文の意味は行単位の比較の規則(9.23.5)に従って理解しなければならないことに注意してください。 例えば、PARTITION BY RANGE (x,y)について、パーティション境界FROM (1, 2) TO (3, 4)には、x=1y>=2の任意の値のもの、x=2でNULLでない任意のyのもの、x=3y<4の任意の値のものが入ります。

範囲パーティションを作るとき、MINVALUEおよびMAXVALUEという特別な値を使用することができて、これらはそれぞれ列の値に下限と上限がないことを示します。 例えば、FROM (MINVALUE) TO (10)で定義されたパーティションには10より小さいすべての値が入り、FROM (10) TO (MAXVALUE)で定義されたパーティションには10以上のすべての値が入ります。

2つ以上の列を含む範囲パーティションを作るとき、MAXVALUEを下限の一部として使うことや、MINVALUEを上限の一部として使うことも意味を持ちえます。 例えば、FROM (0, MAXVALUE) TO (10, MAXVALUE)で定義されたパーティションには、パーティションキーの第1列が0より大きく、かつ10以下であるものが入ります。 同様に、FROM ('a', MINVALUE) TO ('b', MINVALUE)で定義されたパーティションには、パーティションキーの第1列が"a"で始まるすべての行が入ります。

MINVALUEまたはMAXVALUEをパーティション境界の1つの列で使用する場合、それより後の列では同じ値を使用しなければならないことに注意してください。 例えば、(10, MINVALUE, 0)は有効な境界ではありません。 (10, MINVALUE, MINVALUE)とします。

timestamp,など一部の要素型では、"infinity"(無限)の概念があり、それも保存できる値であることにも注意してください。 MINVALUEMAXVALUEは保存できる真の値ではなく、値に境界がないということを表現するための方法に過ぎないため、これとは違います。 MAXVALUEは"infinity"も含め、他のすべての値より大きいものと考えることができ、またMINVALUEは"minus infinity"も含め、他のすべての値より小さいものと考えることができます。 従って、境界FROM ('infinity') TO (MAXVALUE)は空の範囲ではなく、たった1つの値、つまり"infinity"だけを保存します。

DEFAULTが指定された場合、テーブルは親テーブルのデフォルトパーティションとして作成されます。 親はリストパーティションテーブルか範囲パーティションテーブルのいずれかがありえます。 親の他のどのパーティションにも当てはまらないパーティションキー値はデフォルトパーティションに送られます。 ある親テーブルに対してデフォルトパーティションは一つだけ存在できます。

テーブルが既存のDEFAULTパーティションを持っていて、新たなパーティションが追加された場合、既存のデフォルトパーティションは、新たなパーティションに属すのがふさわしい行が含まれていないことを確かめるために、検査されなければなりません。 デフォルトパーティションに多数の行が含まれている場合、これは時間を要すかもしれません。 デフォルトパーティションが、外部テーブルであるか、新パーティションに置くべき行を含むことができないことを証明する制約を持つ場合、この検査は省略されます。

ハッシュパーティションを作るときには法と残余を指定しなければなりません。 法は正の整数でなければならず、残余は法よりも小さい非負整数でなければなりません。 典型的にはハッシュパーティションテーブル初期設定をするとき、パーティションの数と等しい法を選び、全てのテーブルに同じ法と異なる残余を割り当てます(後述の例を参照)。 しかしながら、全てのパーティションが同じ法を持つ必要はなく、あるハッシュパーティションテーブルのパーティションに存在する全ての法が次に大きい法の因子であることだけ必要です。 このことは、全データを一度に移すことなくパーティション数を徐々に増やすことを可能にします。 例えば、各々の法が8である8パーティションのハッシュパーティションテーブルがあるとして、パーティション数を16に増やさなければならなくなったとします。 私たちは8を法とするパーティションの一つをデタッチして、新たに16を法とするキー空間の同じ部分(一つはデタッチしたパーティションと等しい残余を持ち、一つはその値に8を加えたのと等しい残余を持つ)を対象とする二つのパーティションを追加して、データを再配置することができます。 これを(おそらくはより後に)8を法とする各パーティションがなくなるまで、繰り返すことができます。 これは依然として各ステップで大きなデータ移動を伴いますが、全体の新テーブルを作って全データを一度に移さなければならないというよりは、まだ良いです。

パーティションは、それが属するパーティションテーブルと同じ列名および型を持っていなければなりません。 親がWITH OIDSを指定している場合は、すべてのパーティションがOIDを持っていなければならず、親のOIDは他の列と同様にすべてのパーティションに継承されます。 パーティションテーブルの列名や型の変更や、OID列の追加や削除は自動的にすべてのパーティションに反映されます。 CHECK制約はすべてのパーティションで自動的に継承されますが、個々のパーティションで追加のCHECK制約を指定することができます。 親の制約と同じ名前と条件を持つ追加制約は親の制約と統合されます。 デフォルト制約は各パーティションで別々に指定できます。

パーティションテーブルに挿入された行は、自動的に正しいパーティションに回されます。 適当なパーティションが存在しないときは、エラーが発生します。

TRUNCATEのように通常はテーブルとそれを継承するすべての子テーブルに影響を及ぼす操作は、すべてのパーティションに対しても適用されますが、個別のパーティションに対して操作することも可能です。 DROP TABLEでパーティションを削除するには、親テーブルについてACCESS EXCLUSIVEのロックを取得する必要があることに注意してください。

LIKE source_table [ like_option ... ]

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

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

コピーする列のデフォルト式は、INCLUDING DEFAULTSが指定された場合にのみコピーされます。 デフォルトの動作では、デフォルト式がコピーされないため、新しいテーブルのコピーされた列はデフォルト値としてNULLを持つことになります。 nextvalのようにデータベースを変更する関数を呼び出すデフォルトをコピーすると、元のテーブルと新しいテーブルの間に関数的なリンクが作成される場合があることに注意してください。

コピーされる列定義のIDENTITYの指定は、INCLUDING IDENTITYが指定された場合にのみコピーされます。 新しいテーブルの各IDENTITY列には新しいシーケンスが作られ、古いテーブルに紐付けられたシーケンスとは別になります。

非NULL制約は常に新しいテーブルにコピーされます。 CHECK制約は、INCLUDING CONSTRAINTSが指定された場合にのみコピーされます。 列制約とテーブル制約は区別されません。

拡張統計情報はINCLUDING STATISTICSが指定された場合にのみコピーされます。

元のテーブルのインデックス、およびPRIMARY KEYUNIQUEEXCLUDEの制約はINCLUDING INDEXESが指定された場合のみ、新しいテーブル上で作成されます。 新しいインデックスと制約の名前は、元の名前とは関係なく、デフォルトの規則に従って付けられます。 (この動作により、新しいインデックスが名前の重複によりエラーになる可能性を回避しています。)

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

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

INCLUDING ALLINCLUDING COMMENTS INCLUDING CONSTRAINTS INCLUDING DEFAULTS INCLUDING IDENTITY INCLUDING INDEXES INCLUDING STATISTICS INCLUDING STORAGEの省略形です。

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

またLIKE句をビュー、外部テーブル、複合型から列の定義をコピーするために使用することができます。 適用できないオプション(ビューからのINCLUDING INDEXESなど)は無視されます。

CONSTRAINT constraint_name

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

NOT NULL

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

NULL

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

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

CHECK ( expression ) [ NO INHERIT ]

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

現時点では、CHECK式には副問い合わせも現在の行の列以外の変数も含めることはできません。 システム列tableoidを参照することはできますが、他のシステム列は参照できません。

NO INHERITと印が付いた制約は子テーブルには伝搬しません。

テーブルに複数のCHECK制約がある場合、それらはNOT NULL制約について検証した後で、各行について名前のアルファベット順に検証されます。 (PostgreSQLの9.5より前のバージョンでは、CHECK制約の実行について特定の順序はありませんでした。)

DEFAULT default_expr

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

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

GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ( sequence_options ) ]

この句は列をIDENTITY列として作成します。 それには暗示的なシーケンスが紐付けられ、新しい行のその列には紐付けられたシーケンスから取られた値が自動的に入ります。

ALWAYSBY DEFAULTの句は、ユーザがINSERT文で指定した値に対するシーケンスの値の優先度がどうなるかを決定します。 ALWAYSが指定された場合、ユーザが指定した値はINSERT文でOVERRIDING SYSTEM VALUEを指定した場合にのみ受け付けられます。 BY DEFAULTが指定された場合は、ユーザが指定した値が優先します。 詳細はINSERTを参照してください。 (COPYコマンドでは、この設定と関係なく、ユーザが指定した値が常に使用されます。)

オプションでsequence_options句を指定することにより、シーケンスのオプションを変更できます。 詳しくはCREATE SEQUENCEを参照してください。

UNIQUE (列制約)
UNIQUE ( column_name [, ... ] ) [ INCLUDE ( column_name [, ...]) ] (表制約)

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

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

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

複数レベルのパーティション階層に一意性制約を設定するとき、対象パーティションテーブル、および全ての子孫のパーティションテーブルの、パーティションキー内の全ての列が制約定義に含まれなくてはなりません。

一意性制約を加えると、制約で使われている列や列のグループに一意性btreeインデックスが自動的に作られます。 省略可能なINCLUDE句はインデックスに一意性を強要されない列を1つまたは複数、追加します。 含めた(INCLUDEした)列に制約は強制されませんが、依存はしていることに注意してください。 このため、これらの列に対する一部の操作(例えばDROP COLUMN)は制約の連鎖とインデックスの削除をひき起こすことがあります。

PRIMARY KEY (列制約)
PRIMARY KEY ( column_name [, ... ] ) [ INCLUDE ( column_name [, ...]) ] (表制約)

PRIMARY KEY制約はテーブルの一列または複数の列が一意(重複がない)で、非NULLの値のみを持つことを指定します。 列制約か表制約かに関わらず、1つのテーブルには主キーを1つだけ指定できます。

主キー制約では、同じテーブルに一意制約で指定した列の集合とは異なる列の集合を指定します。 (そうでなければ、一意制約は冗長となり、捨てられます。)

PRIMARY KEYUNIQUENOT NULLの組み合わせと同じデータ制約を課しますが、列の集合を主キーと指定することは、スキーマの設計についてのメタデータを提供することにもなります。 なぜなら、主キーであることは、行を一意に特定するものとして、他のテーブルがその列の集合を当てにして良い、ということを意味するからです。

PRIMARY KEY制約は、パーティションテーブルに設定するときにUNIQUE制約が持つ制限を共有します。

PRIMARY KEY制約を追加すると、制約で使用する列や列のグループに一意性のbtreeインデックスが自動的に作られます。 省略可能なINCLUDE句はインデックスの非キー部分に含める列のリストを指定できます。 含めた列に一意性は強制されませんが、制約はこれらに依存はしています。 このため、これらの含められた列に対する一部の操作(例えばDROP COLUMN)は制約の連鎖とインデックスの削除をひき起こすことがあります。

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

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

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

アクセスメソッドはamgettupleをサポートしなければなりません(第61章参照)。 現時点では、これはGINを使用できないことを意味します。 B-treeやHashインデックスを排他制約で使用することは許容されますが、そうすることにあまり意味はありません。 これが通常の一意性制約より良いことは何もないからです。 このため現実的にはアクセスメソッドは常にGiSTもしくはSP-GiSTとなります。

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

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

これらの句は、外部キー制約を指定します。 外部キー制約は、新しいテーブルの1つまたは複数の列の集合が、被参照テーブルの一部の行の被参照列に一致する値を持たなければならないことを指定するものです。 refcolumnリストが省略された場合、reftableの主キーが使用されます。 被参照列は、被参照テーブルにおいて遅延不可の一意性制約もしくは主キー制約を持った列でなければなりません。 ユーザは被参照テーブル(テーブル全体または特定の被参照列)についてREFERENCES権限を持っていなければなりません。 外部キー制約の追加は被参照テーブルにSHARE ROW EXCLUSIVEロックを必要とします。 一時テーブルと永続テーブルとの間で外部キー制約を定義できないことに注意してください。 パーティションテーブルに外部キーを定義できる一方、外部キーテーブルを参照する外部キーは定義できないことにも注意してください。

参照列に挿入された値は、被参照テーブルと被参照列の値に対して、指定した照合型で照会されます。 照合型には3種類があります。 MATCH FULLMATCH PARTIALMATCH SIMPLE(これがデフォルト)照合型です。 MATCH FULLは全ての外部キー列がNULLとなる場合を除き、複数列外部キーのある列がNULLとなることを許可しません。 それらがすべてNULLであれば、その行は被参照テーブル内で一致があることは要求されません。 MATCH SIMPLEは、外部キーの一部がNULLであることを許可します。 それらの一部がNULLであれば、その行は被参照テーブル内で一致があることは要求されません。 MATCH PARTIALはまだ実装されていません。 (当然ですが、NOT NULL制約を参照列に適用し、こうした状態が発生することを防止することができます。)

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

NO ACTION

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

RESTRICT

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

CASCADE

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

SET NULL

参照する列をNULLに設定します。

SET DEFAULT

参照する列をそのデフォルト値に設定します。 (デフォルト値がNULLでない場合は被参照テーブルの中にデフォルト値に一致する行が存在しなければなりません。さもないと操作が失敗します。)

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

DEFERRABLE
NOT DEFERRABLE

制約を遅延させることが可能かどうかを制御します。 遅延不可の制約は各コマンドの後すぐに検査されます。 遅延可能な制約の検査は、(SET CONSTRAINTSコマンドを使用して)トランザクションの終了時まで遅延させることができます。 NOT DEFERRABLEがデフォルトです。 現在、UNIQUEPRIMARY KEYEXCLUDEREFERENCES(外部キー)制約のみがこの句を受け付けることができます。 NOT NULLおよび CHECK制約は遅延させることができません。 遅延可能な制約はON CONFLICT DO UPDATE句を含むINSERT文において、競合解決のために使うことはできないことに注意してください。

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)およびWITH (OIDS=FALSE)と同じです。 OIDSの設定と格納パラメータの設定の両方を指定したい場合は、上述のWITH ( ... )を使用しなければなりません。

ON COMMIT

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

PRESERVE ROWS

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

DELETE ROWS

一時テーブル内の全ての行は、各トランザクションブロックの終わりで削除されます。 実質的には、コミットの度に自動的にTRUNCATEが実行されます。 パーティションテーブルに使われた場合、そのパーティションに連鎖適用はされません。

DROP

一時テーブルは現在のトランザクションブロックの終わりで削除されます。 この動作は、パーティションテーブルに使われたときにそのパーティションを削除し、継承の子テーブルを伴うテーブルに使われたときに従属する子テーブルを削除します。

TABLESPACE tablespace_name

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

USING INDEX TABLESPACE tablespace_name

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

格納パラメータ

WITH句により、テーブルおよびUNIQUEPRIMARY KEY、またはEXCLUDE制約と関連づいたインデックスの格納パラメータを指定することができます。 インデックスの格納パラメータについてはCREATE INDEXで説明します。 現在テーブルで設定可能な格納パラメータの一覧を以下に示します。 これらのパラメータの多くに対して、示した通り、さらにtoastという接頭辞のついた、同一の名前のパラメータがあります。 これはもしあれば、テーブルの補助TOASTテーブルの動作を制御します。 (TOASTに関する詳細については68.2を参照してください。) テーブルのパラメータ値が設定され、それと同等のtoast.パラメータが設定されていない場合、TOASTテーブルはテーブルのパラメータ値を利用します。 これらのパラメータをパーティションテーブルについて指定することはサポートされませんが、個々の末端のパーティションについて指定することはできます。

fillfactor (integer)

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

toast_tuple_target (integer)

toast_tuple_targetは、長い列値をTOASTテーブルに移動する前に必要とされる最小タプル長を指定します。また、これはTOAST化を開始したときに長さをそれ未満に減らそうとする目標にもなります。 これはEXTERNALかEXTENDEDと印付けされた列にのみ影響があり、また、新たなタプルにのみ適用されます。既存の行には影響ありません。 デフォルトでは、このパラメータは1ブロックあたり少なくとも4タプルが可能であるように設定されます。これはデフォルトブロックサイズであれば2040バイトになります。 有効な値は128バイトから、ブロックサイズ - ヘッダ(デフォルトでは8160バイト)の間です。 非常に短いあるいは長い行に対して、この値を変更することはおそらく有用ではありません。 時にはデフォルト設定が最適に近く、本パラメータを設定することで場合によっては悪影響があるかもしれないことに注意してください。

parallel_workers (integer)

このテーブルの並列スキャンを支援するために使用されるワーカの数を設定します。 設定されなければ、リレーションのサイズに基づいてシステムが値を決定します。 プランナやパラレルスキャンを使うユーティリティ文により選ばれるワーカの数は、例えばmax_worker_processesの設定によって、より少なくなるかもしれません。

autovacuum_enabled, toast.autovacuum_enabled (boolean)

特定のテーブルに対する自動バキュームデーモンを有効または無効にします。 trueの場合、自動バキュームデーモンは、更新または削除されたタプル数がautovacuum_vacuum_thresholdautovacuum_vacuum_scale_factor×リレーション内の推定有効タプル数を超えたときに、特定のテーブルに対するVACUUM操作を始めます。 trueの場合、自動バキュームデーモンは、24.1.6に記述されたルールに従って、このテーブルに対して自動的にVACUUMあるいはANALYZEまたはその両方の操作を行います。 falseの場合、トランザクションIDの周回問題を回避するためを除き自動バキュームは行われません。 周回問題の回避については24.1.5を参照してください。 autovacuumパラメータがfalseの場合、(トランザクションIDの周回問題を回避する場合を除き)自動バキュームデーモンはまったく実行されないことに注意して下さい。 個々のテーブルの格納パラメータを設定しても、それは優先されません。 従って、この格納パラメータを明示的にtrueに設定することにはほとんど意味はなく、falseに設定することのみが意味を持ちます。

autovacuum_vacuum_threshold, toast.autovacuum_vacuum_threshold (integer)

autovacuum_vacuum_thresholdパラメータについて、テーブル毎に設定する値です。

autovacuum_vacuum_scale_factor, toast.autovacuum_vacuum_scale_factor (float4)

autovacuum_vacuum_scale_factorパラメータについて、テーブル毎に設定する値です。

autovacuum_analyze_threshold (integer)

autovacuum_analyze_thresholdパラメータについて、テーブル毎に設定する値です。

autovacuum_analyze_scale_factor (float4)

autovacuum_analyze_scale_factorパラメータについて、テーブル毎に設定する値です。

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_table_age, toast.autovacuum_freeze_table_age (integer)

vacuum_freeze_table_ageパラメータについて、テーブル毎に設定する値です。

autovacuum_multixact_freeze_min_age, toast.autovacuum_multixact_freeze_min_age (integer)

vacuum_multixact_freeze_min_ageパラメータについて、テーブル毎に設定する値です。 テーブル単位のautovacuum_multixact_freeze_min_ageパラメータをシステム全体のautovacuum_multixact_freeze_max_ageの半分より大きく設定しても、自動バキュームが無視することに注意してください。

autovacuum_multixact_freeze_max_age, toast.autovacuum_multixact_freeze_max_age (integer)

autovacuum_multixact_freeze_max_ageパラメータについて、テーブル毎に設定する値です。 テーブル単位のautovacuum_multixact_freeze_max_ageをシステム全体に対する設定より大きくしても、自動バキュームが無視することに注意してください(より小さな値しか設定できません)。

autovacuum_multixact_freeze_table_age, toast.autovacuum_multixact_freeze_table_age (integer)

vacuum_multixact_freeze_table_ageパラメータについて、テーブル毎に設定する値です。

log_autovacuum_min_duration, toast.log_autovacuum_min_duration (integer)

log_autovacuum_min_durationパラメータについて、テーブル毎に設定する値です。

user_catalog_table (boolean)

テーブルを論理レプリケーションのための追加のカタログテーブルとして宣言します。 詳しくは49.6.2を参照してください。 このパラメータはTOASTテーブルには設定できません。

注釈

新規のアプリケーションでOIDを使用するのはお勧めしません。 可能であれば、テーブルの主キーとしてIDENTITY列や他のシーケンスジェネレータを使用する方が望ましいです。 しかし、アプリケーションがテーブルの特定の行を識別するために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 GENERATED BY DEFAULT AS IDENTITY,
     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%のフィルファクタを指定して、同じテーブルを作成します。

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 measurement (
    logdate         date not null,
    peaktemp        int,
    unitsales       int
) PARTITION BY RANGE (logdate);

パーティションキーに複数の列がある範囲パーティションテーブルを作成します。

CREATE TABLE measurement_year_month (
    logdate         date not null,
    peaktemp        int,
    unitsales       int
) PARTITION BY RANGE (EXTRACT(YEAR FROM logdate), EXTRACT(MONTH FROM logdate));

リストパーティションテーブルを作成します。

CREATE TABLE cities (
    city_id      bigserial not null,
    name         text not null,
    population   bigint
) PARTITION BY LIST (left(lower(name), 1));

ハッシュパーティションテーブルを作成します。

CREATE TABLE orders (
    order_id     bigint not null,
    cust_id      bigint not null,
    status       text
) PARTITION BY HASH (order_id);

範囲パーティションテーブルのパーティションを作成します。

CREATE TABLE measurement_y2016m07
    PARTITION OF measurement (
    unitsales DEFAULT 0
) FOR VALUES FROM ('2016-07-01') TO ('2016-08-01');

パーティションキーに複数の列がある範囲パーティションテーブルに、パーティションをいくつか作成します。

CREATE TABLE measurement_ym_older
    PARTITION OF measurement_year_month
    FOR VALUES FROM (MINVALUE, MINVALUE) TO (2016, 11);

CREATE TABLE measurement_ym_y2016m11
    PARTITION OF measurement_year_month
    FOR VALUES FROM (2016, 11) TO (2016, 12);

CREATE TABLE measurement_ym_y2016m12
    PARTITION OF measurement_year_month
    FOR VALUES FROM (2016, 12) TO (2017, 01);

CREATE TABLE measurement_ym_y2017m01
    PARTITION OF measurement_year_month
    FOR VALUES FROM (2017, 01) TO (2017, 02);

リストパーティションテーブルのパーティションを作成します。

CREATE TABLE cities_ab
    PARTITION OF cities (
    CONSTRAINT city_id_nonzero CHECK (city_id != 0)
) FOR VALUES IN ('a', 'b');

リストパーティションテーブルにパーティションを作成しますが、それ自体がさらにパーティションになり、それにパーティションを追加します。

CREATE TABLE cities_ab
    PARTITION OF cities (
    CONSTRAINT city_id_nonzero CHECK (city_id != 0)
) FOR VALUES IN ('a', 'b') PARTITION BY RANGE (population);

CREATE TABLE cities_ab_10000_to_100000
    PARTITION OF cities_ab FOR VALUES FROM (10000) TO (100000);

ハッシュパーティションテーブルのパーティションを作成します。

CREATE TABLE orders_p1 PARTITION OF orders
    FOR VALUES WITH (MODULUS 4, REMAINDER 0);
CREATE TABLE orders_p2 PARTITION OF orders
    FOR VALUES WITH (MODULUS 4, REMAINDER 1);
CREATE TABLE orders_p3 PARTITION OF orders
    FOR VALUES WITH (MODULUS 4, REMAINDER 2);
CREATE TABLE orders_p4 PARTITION OF orders
    FOR VALUES WITH (MODULUS 4, REMAINDER 3);

Create a default partition:

CREATE TABLE cities_partdef
    PARTITION OF cities DEFAULT;

互換性

CREATE TABLEは、以下に挙げるものを除いて、標準SQLに従います。

一時テーブル

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

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

また標準SQLではグローバル一時テーブルとローカル一時テーブルを区別しています。 ローカル一時テーブルは各セッション内のSQLモジュールそれぞれ用に内容の集合を分離しますが、その定義はセッション全体で共有されます。 PostgreSQLはSQLモジュールをサポートしませんので、PostgreSQLではこの区別は適切ではありません。

互換性を保持するため、PostgreSQLは一時テーブルの宣言においてGLOBALLOCALキーワードを受け付けますが、これらには現在、何の効果もありません。 PostgreSQLの今後のバージョンでは、これらの意味についてより標準に近い実装を取り入れる可能性がありますので、これらのキーワードの使用は勧めません。

一時テーブル用の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制約との対称性)のために含まれています。 どんな列に対してもデフォルトとなるため、これには意味はありません。

制約の命名

SQL標準ではテーブルとドメインの制約はテーブルやドメインを含むスキーマ中で一意な名前を持たなければなりません。 PostgreSQLはより緩やかで、制約名は特定のテーブルやドメインに付加された制約の中で一意であることだけが求められます。 しかしながら、この追加的な自由はインデックスに基づく制約(UNIQUEPRIMARY KEY、およびEXCLUDE制約)にはありません。なぜなら、関連付けられたインデックスは制約と同じに命名されて、インデックス名は同スキーマ内の全てのリレーションの中で一意でなければならないからです。

今のところ、PostgreSQLNOT NULL制約の名前を全く記録しませんので、これらは一意性の制限の対象ではありません。 これは将来のリリースで変更されるかもしれません。

継承

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

列を持たないテーブル

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

複数のIDENTITY列

PostgreSQLではテーブルに2つ以上のIDENTITY列を持つことを許しています。 標準SQLでは、1つのテーブルは最大で1つのIDENTITY列を持つことができると規定しています。 主にスキーマの変更や移行でより柔軟性を持たせるために、この制約を緩和しています。 INSERTコマンドはOVERRIDING句を1つだけしかサポートせず、これが文全体に適用されるため、複数のIDENTITY列があり、これらの動作が異なる場合は正しくサポートされないことに注意してください。

LIKE

LIKE句は標準SQLにありますが、PostgreSQLで利用可能な多くのオプションは標準にはなく、また標準のオプションの一部はPostgreSQLでは実装されていません。

WITH

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

テーブル空間

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

型付きテーブル

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

PARTITION BY

PARTITION BYPostgreSQLの拡張です。

PARTITION OF

PARTITION OF句はPostgreSQLの拡張です。

関連項目

ALTER TABLE, DROP TABLE, CREATE TABLE AS, CREATE TABLESPACE, CREATE TYPE