CREATE TABLE

名前

CREATE TABLE -- 新しいテーブルの定義

概要

CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE table_name (
    { column_name data_type [ DEFAULT default_expr ] [ column_constraint [, ... ] ]
    | table_constraint
    | LIKE parent_table [ { INCLUDING | EXCLUDING } DEFAULTS ] }  [, ... ]
)
[ INHERITS ( parent_table [, ... ] ) ]
[ WITH OIDS | WITHOUT OIDS ]
[ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]

ここで、column_constraint は以下のとおりです。

[ CONSTRAINT constraint_name ]
{ NOT NULL | NULL | UNIQUE | PRIMARY KEY |
  CHECK (expression) |
  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 ]
{ UNIQUE ( column_name [, ... ] ) |
  PRIMARY KEY ( column_name [, ... ] ) |
  CHECK ( expression ) |
  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 ]

説明

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

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

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

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

省略可能な制約句は、新しい、または、更新された行がその挿入、更新操作を成功させるために満たさなければならない制約(または試験項目)を指定します。 制約は、テーブル内で有効な値集合の定義を補助する SQL オブジェクトです。

制約の定義にはテーブル制約と列制約という 2 つの方法があります。 列制約は列定義の一部として定義されます。 テーブル制約定義は特定の列には拘束されず、複数の列を含有することができます。 また各列制約は、テーブル制約として記述することができます。 列制約は、その制約が 1 つの列にのみ影響する場合の、簡便な記述方法にすぎません。

パラメータ

TEMPORARY or TEMP

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

GLOBAL または LOCALTEMPORARYTEMP の後に記述することができます(省略可能)。 PostgreSQLでは、これらに違いはありません。 互換性を参照してください。

table_name

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

column_name

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

data_type

列のデータ型です。これには、配列指定子が含まれる場合があります。

DEFAULT default_expr

DEFAULT 句はそれを記載した列定義の列にデフォルトデータ値を割り当てます。 その値は任意の無変数式です (副selectと現在のテーブル内の他の列へ交差参照は許可されません)。 デフォルト式のデータ型はその列のデータ型と一致する必要があります。

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

LIKE parent_table [ { INCLUDING | EXCLUDING } DEFAULTS ]

LIKE 句は、新しいテーブルが自動的に全ての列名、そのデータ型、および、非NULL制約を継承するテーブルを指定します。

INHERITS との違いは、作成した後、新しいテーブルと継承されたテーブルとの完全に分離されることです。 新しいテーブルに挿入されたデータは、親テーブルには反映されません。

継承される列用のデフォルト式は、INCLUDING DEFAULTS が指定された場合にのみ含まれます。 デフォルトでは、デフォルト式は含まれません。

INHERITS ( parent_table [, ... ] )

省略可能な INHERITS 句は、新しいテーブルがその列を全て継承するテーブルの一覧を指定します。 複数の親テーブルに同一名の列が存在する場合、そのデータ型も一致していなければ、エラーとして報告されます。 競合がなければ、重複した列は新しいテーブルで 1 つの列の形に融合されます。 新しいテーブルの列名の一覧に継承された列が含まれる場合、同様にそのデータ型は継承した列のデータ型に一致しなければならず、その列定義は 1つに融合されます。 しかし、継承された新しい、同一名称の列定義に、同一の制約を指定する必要はありません。 任意の宣言で提供される制約はすべて、まとめてマージされ、全てが新しいテーブルに適用されます。 新しいテーブルが明示的にその列にデフォルト値を指定していた場合、その列の継承された宣言における全てのデフォルト値は上書きされます。 さもなくば、その列にデフォルト値を指定した親テーブルは全て、同じデフォルト値を持たなければなりません。 この他の場合はエラーになります。

WITH OIDS
WITHOUT OIDS

この省略可能な句は、新しいテーブルの行に OID(オブジェクト識別子) を割り当てるかどうかを指定します。 デフォルトでは OID を持ちます。(OID を持つテーブルを継承する新しいテーブルでは、WITHOUT OIDS を指定したとしても強制的にWITH OIDS となります。)

WITHOUT OIDS を指定することにより、ユーザはテーブルの行のための OID 生成を抑制することができます。 これは、OID の消費を抑え、32 ビットの OID カウンタの回転周期を延長することができますので、巨大なテーブルでは価値がある可能性があります。 カウンタが一周すると、OID の一意性を仮定することができなくなり、その有用性を減少させることになります。 また、WITHOUT OIDSを指定することで、テーブル1行当たり4バイト分そのテーブルをディスクに格納するための容量を軽減され、その分、性能が向上します。

CONSTRAINT constraint_name

省略可能な列制約、テーブル制約の名前です。 指定されなければ、システムが名前を生成します。

NOT NULL

列は NULL 値を持つことができません。

NULL

列は NULL 値を持つことができます。これがデフォルトです。

この句は非標準的な SQL データベースとの互換性のためだけに使用可能です。 新しいアプリケーションでこれを使用しないで下さい。

UNIQUE (column constraint)
UNIQUE ( column_name [, ... ] ) (table constraint)

UNIQUE 制約は、テーブルの1つ以上の別々な列のグループは一意な値のみを持つことができることを指定しています。 一意性テーブル制約の動作は列制約と同様ですが、更に複数列に跨る機能を持ちます。

一意性制約の目的のために、NULL 値は等しいとはみなされなせん。

各一意性テーブル制約は、そのテーブルで定義された他の一意性制約もしくはプライマリキー制約によって名付けられた列の集合とは異なるように列の集合を名付けなければなりません。 (さもなくば、同じ制約が2回あらわれるだけになります。)

PRIMARY KEY (column constraint)
PRIMARY KEY ( column_name [, ... ] ) (table constraint)

プライマリキー制約は、テーブルの1列または複数列が一意な(重複が無い)、非 NULL 値のみを持つことを指定します。 技術的には、PRIMARY KEY は単なるUNIQUENOT NULL の組み合わせですが、プライマリキーは、他のテーブルが一意な行の識別子としてこの列集合に依存することができることを意味しますので、プライマリキーとして列の集合を識別することは、スキーマ設計に関するメタデータも提供します。

1つのテーブルには列制約もしくはテーブル制約として 1 つのプライマリキーのみを指定することができます。

プライマリキー制約は、そのテーブルに定義された他全ての一意性制約で名付けられた列の集合とは異なるように、列の集合に名前を付けなければなりません。

CHECK (expression)

CHECK 句は、新しい、または、変更された行が挿入や更新操作が成功するために満たさなければならない、Boolean型の結果を生成する式を指定します。 列定義内の制約は、その列の値のみを参照しなければなりません。一方、テーブル制約として現れる条件は、複数列を参照することができます。

現在、CHECK 式には、副selectや現在の行内の列以外の値を含むことはできません。

REFERENCES reftable [ ( refcolumn ) ] [ MATCH matchtype ] [ ON DELETE action ] [ ON UPDATE action ] (column constraint)
FOREIGN KEY ( column [, ... ] ) REFERENCES reftable [ ( refcolumn [, ... ] ) ] [ MATCH matchtype ] [ ON DELETE action ] [ ON UPDATE action ] (table constraint)

これらの句は、外部キー制約を指定します。 これは、新しいテーブルの 1 つ以上の列のグループが被参照テーブル reftable の被参照列(複数可) refcolumn 内の値に一致する値のみを持たなければならないことを指定するものです。 refcolumn が省略された場合、reftable のプライマリキーが使用されます。 被参照列は被参照テーブルにおいて、一意性もしくはプライマリキー制約をもった列でなければなりません。

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

更に、被参照列のデータが変更された場合、このテーブルの列のデータに何らかの動作が行なわれます。 ON DELETE 句は被参照テーブルの被参照行が削除された場合の動作を指定します。 同様に ON UPDATE 句は被参照テーブルの被参照列が新しい値に更新された場合に行なわれる動作を指定します。 被参照列に実際に変更がないように行が更新された場合は、動作は行なわれません。 各句について、以下の動作を指定可能です。

NO ACTION

削除もしくは更新が外部キー制約違反となることを示すエラーを発生します。これはデフォルトの動作です。

RESTRICT

NO ACTION と同じです。 ただし、制約の残りが遅延可能かつ遅延状態であったとしても、この動作は遅延されません。

CASCADE

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

SET NULL

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

SET DEFAULT

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

プライマリキー列が頻繁に更新される場合、外部キー列にインデックスを付け、外部キー列に関連した NO ACTIONCASCADE 動作がより効率的に実行できるようにする方がいいでしょう。

DEFERRABLE
NOT DEFERRABLE

これは制約を延期させることが可能かどうかを制御します。 延期させられない制約は各コマンドの後すぐに検査されます。 延期可能な制約の検査は (SET CONSTRAINTS コマンドを使用して)トランザクションの終了時まで延期することができます。 NOT DEFERRABLE がデフォルトです。 現在、外部キー制約のみがこの句を受け付けることができます。他の種類の全ての制約は延期させられません。

INITIALLY IMMEDIATE
INITIALLY DEFERRED

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

ON COMMIT

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

PRESERVE ROWS

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

DELETE ROWS

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

DROP

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

注釈

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 (
    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)
);

CHECK 列制約を定義します。

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

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

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

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 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)
);

互換性

CREATE TABLE は、以下の一覧を除いて、SQL92 に準拠し、SQL99のサブセットとなります。

一時テーブル

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

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

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

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

列検査制約

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

NULL "制約"

NULL "制約" (実際は非制約です)は標準 SQL に対する PostgreSQL 拡張で、他のいくつかのデータベースシステムとの互換性のために含まれています(そして NOT NULL 制約と対称になっています)。 どの列でもこれがデフォルトですので、この存在は邪魔なだけです。

継承

INHERITS 句による複数継承は PostgreSQL言語の拡張です。 SQL99 (SQL92 ではありませんが) は異なった構文と異なった意味論を使った単一継承を定義しています。SQL99 方式の継承はまだ PostgreSQLではサポートされていません。

オブジェクト ID

PostgreSQL の OID という概念は標準ではありません。

無列のテーブル

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

関連項目

ALTER TABLE, DROP TABLE