様々な制約

CREATE TABLEでの記述

応用編4日めで、データベースの構造が決まりました。ここではいよいよ、それをもとに、実際にCREATE TABLEを用いてテーブルを構築していくことになるわけですが、その前に、もう少しCREATE TABLE命令について詳しく説明していくと二します。

すでに説明したように、CREATE TABLEには、様々な制約をつけることができました。そこで、ここではそういった制約をCREATE TABLEで記述する方法を説明し、それをもとに実際にテーブルを構築してみることにします。

列制約と表制約

テーブルには様々な制約がつけられることはすでに説明したとおりです。ここでは、それについて更に詳しく説明します。その制約には大きく分けて、列制約表制約があります。

列制約はCREATE TABLE文で列を定義するのと同時に制約を付加するものです。列定義の後ろを半角スペースで区切って記述します。表制約は列名とデータ型のリストを記述した後に、,(コンマ)で区切って制約を記述します。

これら制約は、列制約のみ、表制約のみで記述できるもの、両方で記述できるものがあります。それらは、以下の表を参考にしてください。(表5-1.)

表5-1.列制約と表制約
列制約のみNOT NULL制約
表制約のみ複合主キー制約
両方可能ユニークキー制約
主キー制約
外部キー制約※
※MySQLでは列制約で外部キーを付加することはできない。

では、実際にこれらの制約の記述方法を具体的にみていくことにしましょう。

主キー制約

まずは、主キー制約の記述方法を見ていきましょう。主キー制約を付加するには「PRIMARY KEY」という記述を使います。表からわかる通り、主キー制約は、列、表、両方で記述可能です。以下、それぞれのケースを見ていきます。

Sampleex501.sql(主キー制約:列制約)
CREATE TABLE sample(
	col1 INTEGER PRIMARY KEY,
	col2 VARCHAR(20),
	col3 TIMESTAMP,
	col4 INTEGER
);

続いて、表制約で主キー制約を付加します。

Sampleex502.sql(主キー制約:表制約)
CREATE TABLE sample(
	col1 INTEGER,
	col2 VARCHAR(30),
	col3 TIMESTAMP,
	col4 INTEGER,
	PRIMARY KEY(col1)
);

表制約では、列名とデータ型のリストの後を,で区切って制約名を記述します。PRIMARY KEYの後に( )をつけその中に制約を付加する列名を記述します。

この例では、col1列が主キーとして設定されます。

複合主キー制約

主キーは、複数設定することができます。これを、複合主キーと言います。たとえば、学生のデータベースなどを作った場合、学生番号と名前の組み合わせは一意になります。そのため、こういったデータは列は複数にまたがっているものの、一つにまとめて主キーとして扱うことができます。(図5-1.)

図5-1.複合主キー
複合主キー

複合主キーを用いる場合は、表制約で記述する必要があり、列は,で区切って記述します。

Sampleex503.sql(複合主キー制約)
CREATE TABLE sample(
	col1 INTEGER,
	col2 VARCHAR(30),
	col3 TIMESTAMP,
	col4 INTEGER,
	PRIMARY KEY(col1,col2)
);

この例では、col1col2列が主キーとして設定されます。

NOT NULL制約

NOT NULL制約は列制約でのみ定義可能です。記述する場合は以下のようになります。

Sampleex504.sql(複合主キー制約)
CREATE TABLE sample(
	col1 INTEGER NOT NULL,
	col2 VARCHAR(30),
	col3 TIMESTAMP,
	col4 INTEGER
);

ユニークキー制約

ユニークキー制約は列制約と表制約の両方で付加することができます。基本的な書式は主キー制約のときと同じですが、SQLでは「UNIQUE」と記述します。

Sampleex506.sql(ユニークキー制約:列制約)
CREATE TABLE sample(
	col1 INTEGER UNIQUE,
	col2 VARCHAR(30),
	col3 TIMESTAMP,
	col4 INTEGER
);

Sampleex507.sql(ユニークキー制約:表制約)
CREATE TABLE sample(
	col1 INTEGER,
	col2 VARCHAR(30),
	col3 TIMESTAMP,
	col4 INTEGER,
	UNIQUE(col1)
);

外部キー制約

外部キー制約はFOREIGN KEY (列名) REFERENCES テーブル名(列名)と記述します。FOREIGN KEYの後の( )内には外部キーを付加する列名、REFERENCESの後には親キーがあるテーブル名を、( )内には親キーの列名を記述します。

そのため、記述例は以下の通りになります。まずは、列制約から見てみましょう。

Sampleex508.sql(外部キー制約:列制約)
CREATE TABLE sample(
	col1 INTEGER REFERENCES sample2(col1),
	col2 VARCHAR(30),
	col3 TIMESTAMP,
	col4 INTEGER
);

列制約ではFOREIGN KEYを省略し、REFERENCESから後のみを記述します。この例では、sample2テーブルのcol1列は主キーに設定されているものとします。同じものを、表制約で記述すると、以下のようになります。

Sampleex509.sql(外部キー制約:列制約)
CREATE TABLE sample(
	col1 INTEGER,
	col2 VARCHAR(30),
	col3 TIMESTAMP,
	col4 INTEGER,
	FOREIGN KEY(col1) REFERENCES sample2(col1)
);

なお、MySQLでは列制約で外部キーを付加しても無視されます。エラーにはなりませんが、外部キーを付加する場合には、表制約を用いましょう

その他の列の定義

制約以外に定義できる内容

テーブルには、制約のほかに、さまざまな情報を付加することが可能です。ここでは、その中で特に重要な、デフォルト値の設定と、オートインクリメントの設定の方法について説明します。

デフォルト値の設定

テーブルを定義するときには、列のデフォルト値を設定することが可能です。データを追加時に、デフォルト値が設定されている列の値が存在しない場合、デフォルト値が入力されることになります。デフォルト値の設定方法は、列のデータ型によって異なります。

まずは、一般的なケースを説明します。一般的に、列を定義した後に半角スペースを空けてDEFAULT デフォルト値と記述します。

Sampleex510.sql(一般的なケース)
CREATE TABLE sample(
	col1 INTEGER DEFAULT 10,
	col2 VARCHAR(30),
	col3 TIMESTAMP,
	col4 INTEGER
);

このサンプルでは、col1列に10というデフォルト値が設定されます。

なお、DEFAULTはNOT NULL制約と合わせて定義できます。この場合の記述方法は、、「col1 INTEGER DEFAULT 10 NOT NULL」と記述するか、「col1 INTEGER NOT NULL DEFAULT 10」と記述します。

Sampleex511.sql(NOT NULL制約との併用)
CREATE TABLE sample(
	col1 INTEGER DEFAULT 10 NOT NULL,
	col2 VARCHAR(30),
	col3 TIMESTAMP,
	col4 INTEGER
);

デフォルト値には関数を使用することもできます。この場合、DEFAULT 関数名()と記述します。

Sampleex512.sql(一般的なケース)
CREATE TABLE sample(
	col1 INTEGER,
	col2 VARCHAR(30),
	col3 TIMESTAMP DEFAULT CURRENT_TIMESTAMP(),
	col4 INTEGER
);

これにより、col3には、INSERT文を実行した時間のタイムスタンプが記入されることになります。

自動インクリメント列

列を定義する際に、AUTO_INCREMENTを指定することによって、その列を自動インクリメント列にすることができます。

インクリメントとは数値を1増やすことで、データの追加時に値が入力されていなければ、前に入力した値から1増やした値を自動的に入力することができます。テーブルの主キーにAUTO_INCREMENTを指定すると大変便利です。

Sampleex512.sql(主キーを自動インクリメントに指定)
CREATE TABLE sample(
	col1 INTEGER AUTO_INCREMENT,
	col2 TIMESTAMP DEFAULT CURRENT_TIMESTAMP(),
	PRIMARY KEY(col1)
);

AUTO_INCREMENTを指定する列は、主キーかユニークキーである必要があります。また、テーブル内でAUTO_INCREMENTを指定することができる列は、一つだけです。

試しに、このテーブルを作成し、以下のSQLを何度か発行してみてください。

Sampleex513.sql
INSERT INTO sample VALUES ();

すると、以下のように、col1のAUTO_INCREMENTの部分の番号が自動発行され、col2にはsql発行時のタイムスタンプが入るのが分かります。(図5-2.)

図5-2.Sampleex513.sqlの実行結果
Sampleex513.sqlの実行結果