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 [, ... ] ) ] [ 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 } [, ... ] ) ] [ 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 | 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 ] 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_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権限を持たなければなりません。
このパラメータが指定された場合、テーブルは一時テーブルとして作成されます。 一時テーブルは、そのセッションの終わり、場合によっては、現在のトランザクションの終わり(後述のON COMMITを参照)に自動的に削除されます。 一時テーブルが存在する場合、同じ名前を持つ既存の永続テーブルは、スキーマ修飾名で参照されていない限り、現在のセッションでは非可視になります。 一時テーブルで作られるインデックスも、全て自動的に一時的なものとなります。
autovacuum daemonは一時テーブルにアクセスできません。 したがって一時テーブルのバキュームや解析を行うことはできません。 このためセッションのSQLコマンドを用いて適切なバキュームと解析を実行しなければなりません。 例えば、一時テーブルが複雑な問い合わせで使用される場合、一時テーブルにデータを投入した後にそれに対しANALYZEを実行することを勧めます。
GLOBALまたはLOCALをTEMPORARYやTEMPの前に記述することができます(省略可能)。 PostgreSQLでは、現在違いがなく、廃止予定です。 互換性を参照してください。
指定された場合、テーブルはログを取らないテーブルとして作成されます。 ログを取らないテーブルに書き出されたデータは先行書き込みログ(第29章参照)には書き出されません。 このため通常のテーブルより相当高速になります。 しかしこれらはクラッシュ時に安全ではありません。 クラッシュまたは異常停止の後、ログを取らないテーブルは自動的に切り詰められます。 またログを取らないテーブルの内容はスタンバイサーバに複製されません。 ログを取らないテーブル上に作成されたインデックスはすべて同様に、ログを取らないようになります。
同じ名前のリレーションがすでに存在していてもエラーとしません。 この場合注意が発せられます。 既存のリレーションが作成しようとしたものと何かしら似たものであることは保証されません。
作成するテーブルの名前です(スキーマ修飾名でも可)。
指定(スキーマ修飾可能)した複合型から構造を取り出した型付きテーブルを作成します。 型付きテーブルはその型に束縛されます。 例えば、型が(DROP TYPE ... CASCADE付きで)削除されるとそのテーブルは削除されます。
型付きテーブルが作成されると、その列のデータ型は背後の複合型により決定され、CREATE TABLEコマンドでは指定されません。 しかしCREATE TABLEコマンドではテーブルにデフォルトと制約を追加できます。 また、格納パラメータの指定も可能です。
新しいテーブルで作成される列の名前です。
列のデータ型です。 これには、配列指定子を含めることができます。 PostgreSQLでサポートされるデータ型の情報に関する詳細は第8章を参照してください。
COLLATE句は列(照合順の設定が可能なデータ型でなければなりません)に照合順を割り当てます。 指定がなければ、列のデータ型のデフォルトの照合順が使用されます。
INHERITS句でテーブルの一覧を指定すると、新しいテーブルは指定されたテーブルの全ての列を自動的に継承します。この句は省略可能です。
INHERITSを使用すると、新しい子テーブルとその親テーブル(複数可)との間に永続的な関連が作成されます。 通常、親へのスキーマ修飾子は同様に子にも伝播します。また、デフォルトでは、親テーブルの走査結果には子テーブルのデータが含まれます。
複数の親テーブルに同一名の列が存在する場合、それらのデータ型が一致していなければ、エラーとして報告されます。 競合がなければ、これらの重複した列は新しいテーブルで1つの列の形に融合されます。 新しいテーブルの列名の一覧に継承する列の名前が含まれる場合も、そのデータ型は継承する列のデータ型と一致していなければなりません。さらに、その列定義は1つに融合されます。 新しいテーブルで明示的に列のデフォルト値を指定した場合、継承した列宣言における全てのデフォルト値は上書きされます。 デフォルト値を指定しなかった場合、親側でデフォルト値が指定されている時は、それらのデフォルト値が全て同じ値でなければなりません。 値が違う場合はエラーになります。
CHECK制約は、基本的には列と同様の方法でマージされます。 複数の親テーブル、新しいテーブル、またはその両方の定義に同じ名前のCHECK制約が存在した場合、これらの制約はすべて同じ検査式を持たなければなりません。 さもなくば、エラーが報告されます。 同じ名前と式を持つ制約は1つのコピーにまとめられます。 親テーブルでNO INHERITと印が付いた制約は考慮されません。 一意な名前が常に選択されますので、新しいテーブル内の無名のCHECK制約はマージされないことに注意してください。
列のSTORAGE設定もまた親テーブルからコピーされます。
LIKE句にテーブルを指定すると、自動的にそのテーブルの全ての列名、そのデータ型、非NULL制約が新しいテーブルにコピーされます。
INHERITSとの違いは、作成した後、新しいテーブルと元のテーブルが完全に分離されることです。 元のテーブルへの変更は新しいテーブルには適用されません。また、元のテーブルを操作しても新しいテーブルのデータは見つかりません。
コピーする列のデフォルト式は、INCLUDING DEFAULTSが指定された場合にのみコピーされます。 デフォルトでは、デフォルト式がコピーされないため、新しいテーブルのコピーされた列はデフォルト値としてNULLを持つことになります。
非NULL制約は常に新しいテーブルにコピーされます。 CHECK制約は、INCLUDING CONSTRAINTSが指定された場合にのみコピーされます。 元のテーブル上のインデックス、PRIMARY KEY、およびUNIQUE制約は、INCLUDING INDEXESが指定された場合にのみ新しいテーブル上に作成されます。 列制約とテーブル制約とを区別しません。
複製された列定義に関するSTORAGE設定は、INCLUDING STORAGEが指定された場合のみコピーされます。 このデフォルトの動作では、STORAGE設定は除外され、新しいテーブルにおけるコピーされた列は型固有のデフォルトの設定を持つようになります。 STORAGEの詳細については項58.2を参照してください。
コピーされた列、制約、インデックスについてのコメントはINCLUDING COMMENTSが指定された場合のみコピーされます。 このデフォルトの動作では、コメントは除外され、新しいテーブルにおけるコピーされた列や制約はコメントを持ちません。
INCLUDING ALLはINCLUDING DEFAULTS INCLUDING CONSTRAINTS INCLUDING INDEXES INCLUDING STORAGE INCLUDING COMMENTSの省略形です。
また、INHERITSと異なり、LIKEによりコピーされた列や制約は類似の名前の列や制約にまとめられません。 同じ名前が明示的に、あるいは他のLIKE句で指定された場合、エラーが通知されます。
またLIKE句をビュー、外部テーブル、複合型から列をコピーするために使用することができます。 不適切なオプション(ビューからのINCLUDING INDEXESなど)は無視されます。
省略可能な列制約、テーブル制約の名前です。 もし、この制約に違反すると、制約名がエラーメッセージに含まれるようになります。 ですので、col must be positive(正数でなければならない)といった名前の制約名を付与することで、クライアントアプリケーションへ有用な制約情報を渡すことができます。 (空白を含む制約名を指定する場合、二重引用符が必要です。) 指定されなければ、システムが名前を生成します。
その列がNULL値を持てないことを指定します。
その列がNULL値を持てることを指定します。 これがデフォルトです。
この句は非標準的なSQLデータベースとの互換性のためだけに提供されています。 新しいアプリケーションでこれを使用するのはお勧めしません。
CHECKは、論理型の結果を生成する、新しい行または更新される行が挿入または更新処理を成功させるために満足しなければならない式を指定します。 TRUEまたはUNKNOWNと評価される式は成功します。 挿入または更新処理の行がFALSEという結果をもたらす場合はエラー例外が発生し、その挿入または更新によるデータベースの変更は行われません。 列制約として指定された検査制約は列の値のみを参照しなければなりません。 テーブル制約内の式は複数の列を参照できます。
現時点では、CHECK式には副問い合わせも現在の行の列以外の変数を含めることはできません。
NO INHERITと印が付いた制約は子テーブルには伝搬しません。
DEFAULT句を列定義に付けると、その列にデフォルトデータ値が割り当てられます。 値として指定するのは、任意の無変数式です(副問い合わせと現在のテーブル内の他の列へ交差参照は許可されません)。 デフォルト式のデータ型はその列のデータ型と一致する必要があります。
デフォルト式は、全ての挿入操作において、その列に値が指定されていない場合に使用されます。 列にデフォルト値がない場合、デフォルト値はNULLになります。
UNIQUE制約は、テーブルの1つまたは複数の列からなるグループが、一意な値のみを持つことができることを指定します。 一意性テーブル制約の動作は一意性列制約と同じですが、さらに複数列にまたがる機能を持ちます。
一意性制約では、NULL値は等しいとはみなされなせん。
それぞれの一意性テーブル制約には、そのテーブルの他の一意性制約もしくはプライマリキー制約によって名付けられた列の集合とは、異なる名前の列の集合を指定しなければなりません (同じ名前を指定すると、同じ制約が2回現れるだけになります)。
プライマリキー制約は、テーブルの1列または複数列が一意な(重複がない)、非NULL値のみを持つことを指定します。 技術的には、PRIMARY KEYは単なるUNIQUEとNOT NULLの組み合わせです。 しかし、プライマリキーであることは他のテーブルがその列集合を一意な行識別子とみなせることを意味するので、列集合をプライマリキーと特定すると、スキーマ設計に関するメタデータを提供することになります。
列制約であるかテーブル制約であるかにかかわらず、1つのテーブルに指定できるプライマリキーは1つだけです。
プライマリキー制約には、そのテーブルに定義された他の一意性制約で指名された列の集合とは違う組み合わせの列の集合を指定しなければなりません。
EXCLUDE句は、任意の2行を指定した列(複数可)または式(複数可)を指定した演算子(複数可)を使用して比較した場合、比較結果のすべてがTRUEを返さないことを保障する、除外制約を定義します。 指定した演算子のすべてが等価性を試験するものであれば、これはUNIQUE制約と同じです。 しかし、通常の一意性制約のほうが高速です。 しかし、除外制約では単純な等価性よりも一般的な制約を指定することができます。 例えば、テーブル内の2つの行が重複しない円(項8.8参照)を持たないといった制約を&&演算子を使用して指定することができます。
除外制約はインデックスを使用して実装されています。 このため指定した演算子はそれぞれ適切な演算子クラス(項11.9参照)でindex_methodインデックスアクセスメソッドと関連付けされていなければなりません。 演算子は交換可能でなければなりません。 省略可能ですが、各exclude_elementは演算子クラス、順序付けオプション、またはその両方を指定することができます。 これらについてはCREATE INDEXで説明します。
アクセスメソッドはamgettupleをサポートしなければなりません(第54章参照)。 現時点では、これはGINを使用できないことを意味します。 許されることですが、B-treeやHashインデックスを除外制約で使用する場合に少し問題があります。 これが通常の一意性制約がよりよく行わないことを行うためです。 このため現実的にはアクセスメソッドは常にGiSTもしくはSP-GiSTとなります。
predicateにより、除外制約をテーブルの部分集合に指定することができます。 内部的には、これは部分インデックスを作成します。 述語の前後に括弧が必要であることに注意して下さい。
これらの句は、外部キー制約を指定します。 外部キー制約は、新しいテーブルの1つまたは複数の列の集合が、被参照テーブルの一部の行の被参照列(複数可)に一致する値を持たなければならないことを指定するものです。 refcolumnリストが省略された場合、reftableのプライマリキーが使用されます。 被参照列は、被参照テーブルにおいて遅延不可の一意性制約もしくはプライマリキー制約を持った列でなければなりません。 一時テーブルと永続テーブルとの間で外部キー制約を定義できないことに注意してください。
参照列に挿入された値は、被参照テーブルと被参照列の値に対して、指定した照合型で照会されます。 照合型には3種類があります。 MATCH FULL、MATCH PARTIAL、MATCH SIMPLE(これがデフォルト)照合型です。 MATCH FULLは全ての外部キー列がNULLとなる場合を除き、複数列外部キーのある列がNULLとなることを許可しません。 それらがすべてNULLであれば、その行は被参照テーブル内で一致があることは要求されません。 MATCH SIMPLEは、外部キーの一部がNULLであることを許可します。 それらの一部がNULLであれば、その行は被参照テーブル内で一致があることは要求されません。 MATCH PARTIALはまだ実装されていません。 (当然ですが、NOT NULL制約を参照列に適用し、こうした状態が発生することを防止することができます。)
さらに、被参照列のデータが変更された場合、このテーブルの列のデータに何らかの動作が発生します。 ON DELETE句は、被参照テーブルの被参照行が削除された場合の動作を指定します。 同様にON UPDATE句は、被参照テーブルの被参照列が新しい値に更新された場合の動作を指定します。 行の更新があった場合でも、被参照列が実際に変更されない場合は、動作は実行されません。 制約が遅延可能と宣言されていても、NO ACTION検査以外の参照動作は遅延させられません。 各句について、以下の動作を指定可能です。
削除もしくは更新が外部キー制約違反となることを示すエラーを発生します。 制約が遅延可能な場合、何らかの参照行が存在する限り、このエラーは制約の検査時点で発生します。 これはデフォルトの動作です。
削除もしくは更新が外部キー制約違反となることを示すエラーを発生します。 検査が遅延できない点を除き、NO ACTIONと同じです。
削除された行を参照している行は全て削除します。また、参照している列の値を、被参照列の新しい値にします。
参照する列(複数可)をNULLに設定します。
参照する列(複数可)をそのデフォルト値に設定します。 (デフォルト値がNULLでない場合は被参照テーブルの中にデフォルト値に一致する行が存在しなければなりません。さもないと操作が失敗します。)
被参照列が頻繁に更新される場合、参照列にインデックスを付け、その外部キー制約に関連する参照動作がより効率的に実行できるようにする方が良いでしょう。
制約を遅延させることが可能かどうかを制御します。 遅延不可の制約は各コマンドの後すぐに検査されます。 遅延可能な制約の検査は、(SET CONSTRAINTSコマンドを使用して)トランザクションの終了時まで遅延させることができます。 NOT DEFERRABLEがデフォルトです。 現在、UNIQUE、PRIMARY KEY、EXCLUDE、REFERENCES(外部キー)制約のみがこの句を受け付けることができます。 NOT NULLおよび CHECK制約は遅延させることができません。
制約が遅延可能な場合、この句は制約検査を行うデフォルトの時期を指定します。 制約がINITIALLY IMMEDIATEの場合、各文の実行後に検査されます。 これがデフォルトです。 制約がINITIALLY DEFERREDの場合、トランザクションの終了時にのみ検査されます。 制約検査の時期はSET CONSTRAINTSコマンドを使用して変更することができます。
この句は、テーブルまたはインデックスに対して省略可能な格納パラメータを指定します。 詳細は格納パラメータを参照してください。 テーブル用の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) and WITH (OIDS=FALSE)と同じです。 OIDSの設定と格納パラメータの設定の両方を指定したい場合は、上述のWITH ( ... )を使用しなければなりません。
ON COMMITを使用して、トランザクションブロックの終了時点での一時テーブルの動作を制御することができます。 以下の3つのオプションがあります。
トランザクションの終了時点で、特別な動作は行われません。 これがデフォルトの動作です。
一時テーブル内の全ての行は、各トランザクションブロックの終わりで削除されます。 基本的には、コミットの度に自動的にTRUNCATEが実行されます。
一時テーブルは、現在のトランザクションブロックの終了時点で削除されます。
tablespace_nameは、新しいテーブルが作成されるテーブル空間名です。 指定されていない場合、default_tablespace、もし一時テーブルの場合はtemp_tablespacesが考慮されます。
この句により、UNIQUE、PRIMARY KEY、またはEXCLUDE制約に関連したインデックスを作成するテーブル空間を選択することができます。 指定されていない場合、default_tablespace、もし一時テーブルであればtemp_tablespacesが考慮されます。
WITH句により、テーブルおよびUNIQUE、PRIMARY KEY、またはEXCLUDE制約と関連づいたインデックスの格納パラメータを指定することができます。 インデックスの格納パラメータについてはCREATE INDEXで説明します。 現在テーブルで設定可能な格納パラメータの一覧を以下に示します。 各パラメータに対して、注記がない限り、さらにtoastという接頭辞のついた、同一の名前のパラメータがあります。 これはもしあれば、テーブルの補助TOASTテーブルの動作を制御するために使用することができます。 (TOASTに関する詳細については項58.2を参照してください。) TOASTテーブルは、toast.autovacuum_*の設定群がない場合に親テーブルのautovacuum値を継承することに注意してください。
テーブルのフィルファクタは10から100までの間の割合(パーセント)です。 100(完全にすべて使用)がデフォルトです。 より小さな値を指定すると、INSERT操作は指定した割合までしかテーブルページを使用しません。 各ページの残りの部分は、そのページ内の行更新用に予約されます。 これによりUPDATEは、元の行と同じページ上に更新済みの行の複製を格納することができるようになります。 これは別のページに更新済みの行の複製を格納することよりも効率的です。 項目の更新がまったくないテーブルでは、完全にすべてを使用することが最善の選択です。 しかし、更新が非常に多いテーブルではより小さめのフィルファクタが適切です。 TOASTテーブルではこのパラメータを設定できません。
特定のテーブルに対する自動バキュームデーモンを有効または無効にします。 真の場合、自動バキュームデーモンは、更新または削除されたタプル数がautovacuum_vacuum_threshold+autovacuum_vacuum_scale_factor×リレーション内の推定有効タプル数を超えたときに、特定のテーブルに対するVACUUM操作を始めます。 同様に、挿入、更新、削除されたタプル数がautovacuum_analyze_threshold+autovacuum_analyze_scale_factor×リレーション内の推定有効タプル数を超えたときに、ANALYZE操作を始めます。 偽の場合、トランザクション周回問題を回避するため以外で自動バキュームは行われません。 周回問題の回避については項23.1.5を参照してください。 この変数がautovacuumからの値を継承していることに気付いてください。
特定のテーブルに対してVACUUM操作を始める前の、更新または削除されたタプルの最小数です。
autovacuum_vacuum_thresholdに加算するreltuples用の乗数です。
特定のテーブルに対してANALYZE操作を始める前の、挿入、更新または削除されたタプルの最小数です。
autovacuum_analyze_thresholdに加算するreltuples用の乗数です。
autovacuum_vacuum_cost_delay独自パラメータです。
autovacuum_vacuum_cost_limit独自パラメータです。
vacuum_freeze_min_age独自パラメータです。 テーブル単位のautovacuum_freeze_min_ageをシステム全体のautovacuum_freeze_max_age設定の1/2より大きく設定しようとしても、自動バキュームが無視することに注意してください。
autovacuum_freeze_max_age独自パラメータです。 テーブル単位のautovacuum_freeze_max_ageをシステム全体のに対する設定より大きく設定しようとしても、自動バキュームが無視することに注意してください。 (より小さな値しか設定できません。) autovacuum_freeze_max_ageを非常に小さく設定する、ゼロに設定することすらできますが、頻繁なバキューム処理が強制されるため通常は勧められません。
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データベースと似ています。
また標準SQLではグローバル一時テーブルとローカル一時テーブルを区別しています。 ローカル一時テーブルは各セッション内のSQLモジュールそれぞれ用に内容の集合を分離しますが、その定義はセッション全体で共有されます。 PostgreSQLはSQLモジュールをサポートしませんので、PostgreSQLではこの区別は適切ではありません。
互換性を保持するため、PostgreSQLは一時テーブルの宣言においてGLOBALとLOCALキーワードを受け付けますが、これらには現在、何の効果もありません。 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にはこの制限はありません。 列検査制約とテーブル検査制約を同様のものとして扱っています。
NULL"制約"(実際には非制約)は、標準SQLに対するPostgreSQLの拡張で、他のいくつかのデータベースシステムとの互換性のために含まれています(NOT NULL制約と対称になります)。 どんな列に対してもデフォルトとなるため、これはノイズに過ぎません。
INHERITS句による複数継承は、PostgreSQLの言語拡張です。 SQL:1999以降では、異なる構文と意味体系による単一継承を定義しています。 今のところ、SQL:1999方式の継承はPostgreSQLではサポートされていません。