CREATE [ [ LOCAL ] { TEMPORARY | TEMP } ] TABLE table_name ( { column_name data_type [ DEFAULT default_expr ] [ column_constraint [, ... ] ] | table_constraint } [, ... ] ) [ INHERITS ( parent_table [, ... ] ) ] [ WITH OIDS | WITHOUT OIDS ] ここで、column_constraint は以下のとおりです。 [ CONSTRAINT constraint_name ] { NOT NULL | NULL | UNIQUE | PRIMARY KEY | CHECK ( expression ) | REFERENCES reftable [ ( refcolumn ) ] [ MATCH FULL | MATCH PARTIAL ] [ ON DELETE action ] [ ON UPDATE action ] } [ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ] また、table_constraint は以下のとおりです。 [ CONSTRAINT constraint_name ] { UNIQUE ( column_name [, ... ] ) | PRIMARY KEY ( column_name [, ... ] ) | CHECK ( expression ) | FOREIGN KEY ( column_name [, ... ] ) REFERENCES reftable [ ( refcolumn [, ... ] ) ] [ MATCH FULL | MATCH PARTIAL ] [ ON DELETE action ] [ ON UPDATE action ] } [ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]
CREATE TABLE は新しい、空のテーブルを現在のデータベースに作成します。テーブルはこのコマンドを実行したユーザによって所有されます。
スキーマ名が付けられている場合 (たとえば、CREATE TABLE myschema.mytable ...)、テーブルは指定されたスキーマで作成されます。 スキーマ名がなければ、テーブルは現在のスキーマ (検索パスの前にあるスキーマ。CURRENT_SCHEMA() 参照) で作成されます。 また、TEMP テーブルは特別なスキーマに存在するため、TEMP テーブルの作成時にスキーマ名を与えられない場合もあります。 テーブル名は、同じスキーマ内の他のテーブル、シーケンス、インデックス、もしくはビューとは異なる名前にする必要があります。
CREATE TABLE はまた自動的に、そのテーブルの 1 行に対応するタプル型(構造体型)を表す、データ型を作成します。 したがって、テーブルは、同じスキーマ内の既存のデータ型と同じ名前を持つことができません。
テーブルは 1600 列以上の列を持つことはできません。(実際は、タプル長の制限により実際の制限はもっと低くなります。)
省略可能な制約句は、新しい、または更新された行がその操作を成功させるために満たさなければならない制約(または試験)を指定します。 制約とは名前付きルールであり、テーブルに対する挿入、更新、削除操作の結果に対して制限を持たせることで有効な値集合の定義を補助する SQL オブジェクトです。
制約の定義にはテーブル制約と列制約という 2 つの方法があります。列制約は列定義の一部として定義されます。テーブル制約定義は特定の列には拘束されず、複数の列を含有することができます。また各列制約は、テーブル制約として記述することができます。列制約は、その制約が 1 つの列にのみ影響する場合の、簡便な記述方法にすぎません。
指定された場合、テーブルは一時テーブルとして作成されます。一時テーブルは、そのセッションの終りに自動的に削除されます。 一時テーブルが存在する場合、同じ名前を持つ既存の永続テーブルはスキーマ修飾された名前で参照されていなければ、現在のセッションでは非可視です。一時テーブルで作られるどのインデックスも自動的に一時のものになります。
LOCAL という単語は省略可能です。しかし、 互換性 を参照して下さい。
作成するテーブルの名前です (スキーマ修飾名でも可)。
新しいテーブルで作成される列の名前です。
列のデータ型です。これには、配列指定子が含まれる場合があります。データ型と配列のより詳細については ユーザガイド を参照して下さい。
DEFAULT 句はそれを記載した列定義の列にデフォルトデータ値を割り当てます。その値は任意の無変数式です (副selectと現在のテーブル以外の列へ交差参照は許可されません)。デフォルト式のデータ型はその列のデータ型と一致する必要があります。
デフォルト式は、その列に値が指定されない、全ての挿入操作において使用されます。列にデフォルトがない場合、デフォルト値は NULL になります。
省略可能な INHERITS 句は、新しいテーブルがその列を全て継承するテーブルの一覧を指定します。複数の親テーブルに同一名の列が存在する場合、そのデータ型も一致していなければ、エラーとして報告されます。競合がなければ、重複した列は新しいテーブルで 1 つの列の形にマージされます。新しいテーブルの列名の一覧に、継承された列が含まれる場合、同様にそのデータ型は継承した列のデータ型に一致しなければならず、その列定義は 1つにマージされます。しかし、継承された新しい、同一名称の列定義に、同一の制約を指定する必要はありません。任意の宣言で提供される制約はすべて、まとめてマージされ、全ては新しいテーブルに適用されます。新しいテーブルが明示的にその列にデフォルト値を指定していた場合、その列の継承された宣言における全てのデフォルト値は上書きされます。さもなくば、その列にデフォルト値を指定した親テーブルは全て、同じデフォルト値を持たなければなりません。 この他の場合はエラーになります。
この省略可能な句は、新しいテーブルの行に OID(オブジェクト識別子) を割り当てるかどうかを指定します。デフォルトでは OID を持ちます。(OID を持つテーブルを継承する新しいテーブルでは、WITHOUT OIDS を指定したとしても強制的にWITH OIDS となります。)
WITHOUT OIDS を指定することにより、ユーザはテーブルの行のための OID 生成を抑制することができます。これは、OID の消費を現象し、32 ビットの OID カウンタの回転周期を延長することができますので、巨大なテーブルでは価値がある可能性があります。カウンタが一周すると、OID の一意性を仮定することができなくなり、その有用性を減少させることになります。
省略可能な列制約、テーブル制約の名前です。指定されなければ、システムが名前を生成します。
列は NULL 値をもつことができません。
列は NULL 値を持つことができます。これがデフォルトです。
この句は非標準的な SQL データベースとの互換性のためだけに使用可能です。新しいアプリケーションでこれを使用しないで下さい。
UNIQUE 制約は、テーブルの1つ以上の別々な列のグループは一意な値のみを持つことができることを指定しています。一意性テーブル制約の動作は列制約と同様ですが、更に複数列に跨る機能を持ちます。
一意性制約の目的のために、NULL 値は等しいとはみなされなせん。
各一意性テーブル制約は、そのテーブルで定義された他の一意性もしくはプライマリキー制約によって名付けられた列の集合とは異なるように列の集合を名付けなければなりません。(さもなくば、同じ制約が2回あらわれるだけになります。)
プライマリキー制約は、テーブルの1列または複数列が一意な(重複が無い)、非 NULL 値のみを持つことを指定します。技術的には、PRIMARY KEY は単なるUNIQUE と NOT NULL の組み合わせですが、プライマリキーは、他のテーブルが一意な行の識別子としてこの列集合に依存することができることを意味しますので、プライマリキーとし列の集合を識別することは、スキーマ設計に関するメタデータも提供します。
1つのテーブルには列制約もしくはテーブル制約として 1 つのプライマリキーのみを指定することができます。
プライマリキー制約は、そのテーブルに定義された他全ての一意性制約で名付けられた列の集合とは異なるように、列の集合に名前を付けなければなりません。
CHECK 句は、新しい、または、変更された行が挿入や更新操作が成功するために満たさなければならない、整合性制約や試験を指定します。各制約は、Boolean 型の結果を生成する式である必要があります。列定義内の制約は、その列の値のみを参照しなければなりません。一方、テーブル制約として現れる条件は、複数列を参照することができます。
現在、CHECK 式には、副selectや現在の行の列以外の値を含むことはできません。
REFERENCES 列制約は、新しいテーブルの 1 つ以上の列のグループが被参照テーブル reftable の被参照列 refcolumn 内の値に一致する値のみを持たなければならないことを指定します。refcolumn が省略された場合、reftable のプライマリキーが使用されます。被参照列は被参照テーブルにおいて、一意性もしくはプライマリキー制約をもった列でなければなりません。
これらの列に追加された値は、被参照テーブルと被参照列の値に指定された照合型で照会されます。3種類の照合型があります。MATCH FULL、MATCH PARTIAL、指定が無い場合のデフォルトの照合型です。MATCH FULL は全ての外部キー列が NULL となる場合を除き、複数列外部キーのある列がNULLとなることを許可しません。デフォルトの照合型は、外部キーの他の部分が NULL でない限り、外部キーの一部を NULL となることを許可します。MATCH PARTIAL はまだ実装されていません。
更に、被参照列のデータが変更された場合、このテーブルの列のデータに何らかの動作が行なわれます。ON DELETE 句は被参照テーブルの被参照行が削除された場合の動作を指定します。同様に ON UPDATE 句は被参照テーブルの被参照列が新しい値に更新された場合に行なわれる動作を指定します。被参照列に実際に変更がないように行が更新された場合は、動作は行なわれません。各句について、以下の動作を指定可能です。
削除もしくは更新が外部キー制約違反となることを示すエラーを 表示します。これはデフォルトの動作です。
NO ACTION と同じです。
削除された行を参照する行を全て削除、もしくは、被参照列の新しい値に、参照する列の値を更新します。
参照する列の値を NULL に設定します。
参照する列の値をそのデフォルト値に設定します。
プライマリキー列が頻繁に更新される場合、REFERENCES 列にインデックスを付け、REFERENCES 列に関連した NO ACTION や CASCADE 動作がより効率的に実行できるようにする方がいいでしょう。
これは制約を延期させることが可能かどうかを制御します。延期させられない制約は各コマンドの後すぐに検査されます。延期可能な制約の検査は (SET CONSTRAINTS コマンドを使用して)トランザクションの終了時まで延期することができます。NOT DEFERRABLE がデフォルトです。現在、外部キー制約のみがこの句を受け付けることができます。他の種類の全ての制約は延期させられません。
制約が延期可能な場合、この句は制約検査を行なうデフォルトの時期を指定します。制約が INITIALLY IMMEDIATE の場合、各文の実行後に検査されます。これがデフォルトです。制約がINITIALLY DEFERRED の場合、トランザクションの終了時にのみ検査されます。制約検査の時期は SET CONSTRAINTS コマンドを使用して変更することができます。
アプリケーションがテーブルの特定の行を識別するために OID の使用を行なう場合は、そのテーブルの oid 列に UNIQUE 制約を作成することを推奨します。 これによりカウンタが一周してしまった場合でも一意に行を識別できることが保証されるからです。データベース全体の一意な識別子が必要となる場合、OID がテーブル全体で一意であると仮定することは止めて下さい。 この場合は tableoid と 行の OID の組み合わせを使用して下さい。 (今後の PostgreSQL のリリースでは、各テーブル毎に別々の OID カウンタを使用する予定です。つまり、データベース全体で一意な識別子を得るために tableoid を使用することは、省略できることではなく、必要なことになります。)
Tip: WITHOUT OIDS の使用は、プライマリキーの無いテーブルでは推奨できません。 OID も一意なデータキーも存在しませんので、特定行の識別を行なうことが難しくなるからです。
PostgreSQL は自動的に各一意性制約とプライマリキー制約に対してインデックスを作成し、その一意性を確実なものにします。従って、プライマリキーの列に明示的なインデックスを作成することは必要ありません。(より詳細については CREATE INDEX を参照して下さい。)
SQL92 標準では、CHECK 列制約はそれを適用する列のみを参照でき、CHECK テーブル制約は複数の列を参照できるとしています。PostgreSQL ではこの制限を強制しません。列制約もテーブル制約も同様に扱います。
現在の実装では、一意性制約とプライマリキーは継承されません。これは継承と一意性制約の組み合わせはその機能に障害が起こるからです。
films テーブルと distributors テーブルを作成します。
CREATE TABLE films ( code CHARACTER(5) CONSTRAINT firstkey PRIMARY KEY, title CHARACTER VARYING(40) NOT NULL, did DECIMAL(3) NOT NULL, date_prod DATE, kind CHAR(10), len INTERVAL HOUR TO MINUTE );
CREATE TABLE distributors ( did DECIMAL(3) PRIMARY KEY DEFAULT NEXTVAL('serial'), name VARCHAR(40) NOT NULL CHECK (name <> '') );
2次元配列をもつテーブルを作成します。
CREATE TABLE array ( vector INT[][] );
films テーブルに 一意性テーブル制約を定義します。一意性テーブル制約はテーブルの 1 つ以上の列に定義することができます。
CREATE TABLE films ( code CHAR(5), title VARCHAR(40), did DECIMAL(3), date_prod DATE, kind VARCHAR(10), len INTERVAL HOUR TO MINUTE, CONSTRAINT production UNIQUE(date_prod) );
CHECK 列制約を定義します。
CREATE TABLE distributors ( did DECIMAL(3) CHECK (did > 100), name VARCHAR(40) );
CHECK テーブル制約を定義します。
CREATE TABLE distributors ( did DECIMAL(3), name VARCHAR(40) CONSTRAINT con1 CHECK (did > 100 AND name <> '') );
films テーブルにプライマリキーテーブル制約を定義します。プライマリキーテーブル制約はテーブルの 1 つ以上の列に定義することができます。
CREATE TABLE films ( code CHAR(5), title VARCHAR(40), did DECIMAL(3), date_prod DATE, kind VARCHAR(10), len INTERVAL HOUR TO MINUTE, CONSTRAINT code_title PRIMARY KEY(code,title) );
distributors テーブルにプライマリキー制約を定義します。以下の 2 つの例は同じものです。 前者はテーブル制約構文を使用し、後者は列制約記法を使用します。
CREATE TABLE distributors ( did DECIMAL(3), name CHAR VARYING(40), PRIMARY KEY(did) );
CREATE TABLE distributors ( did DECIMAL(3) 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 DECIMAL(3) CONSTRAINT no_null NOT NULL, name VARCHAR(40) NOT NULL );
name 列に対し、一意性制約を定義します。
CREATE TABLE distributors ( did DECIMAL(3), name VARCHAR(40) UNIQUE );
上のコマンドはテーブル制約として指定した以下のコマンドと等価です。
CREATE TABLE distributors ( did DECIMAL(3), name VARCHAR(40), UNIQUE(name) );
CREATE TABLE は、以下の一覧およびこれまで説明した点を除いて、中級 SQL92 と SQL99 の一部を批准します。
局所的な一時テーブルに加え、SQL92 では CREATE GLOBAL TEMPORARY TABLE 文を定義しています。大域的な一時テーブルは他のセッションからも可視です。
一時テーブルに関して、以下に示す省略可能な ON COMMIT 句があります。
CREATE { GLOBAL | LOCAL } TEMPORARY TABLE table ( ... ) [ ON COMMIT { DELETE | PRESERVE } ROWS ]
ON COMMIT 句は COMMIT が実行された時、一時テーブルの行を空にするかどうかを指定します。ON COMMIT 句が省略された場合、SQL92 で そのデフォルトは ON COMMIT DELETE ROWS と規定しています。しかし、PostgreSQL の動作は常に ON COMMIT PRESERVE ROWS のようにな ります。
NULL "制約" (実際は非制約です)は SQL92 に対する PostgreSQL 拡張で、他の RDBMS との互換性のために含まれています(そして NOT NULL 制約と対称になっています)。どの列でもこれがデフォルトですので、この存在は邪魔なだけです。
表明は、整合性制約の特別な種類であり、他の制約と同じ名前空間を共有します。しかし、表明は制約のように特定のテーブルに依存する必要はありません。 ですので、SQL92 は 制約の定義の別方法として CREATE ASSERTION 文を用意しています。
CREATE ASSERTION name CHECK ( condition )
現在、PostgreSQL は表明を実装していません。