前回に紹介したテーブル作成のSQLであるCREATE TABLEコマンドには「制約」オプションがある。テーブル内に書き込むデータを制限できるので,誤入力防止に役立つ。

 前回,テーブルを作成するCREATE TABLEコマンドの基本構文を,次のように紹介した。


CREATE TABLE テーブル名 (列名 データ型 [, 列名2 データ型 ....]);

 もちろん,基本構文はこの通りなのだが,CREATE TABLEコマンドにはさまざまなオプションが用意されている。これらのオプションには,今後PostgreSQLを使っていく上で知っておきたいものがいくつかある。なかでもよく使われるのが,今回紹介する「制約」だ。

 詳細を解説する前に,具体例を見てみよう。例えば,データベースのテーブル内に,価格を扱う列があり,その列にINTEGER型を指定したとする。INTEGER型は4バイトの整数型であるため,この列には0または正負の整数値を挿入できる。ただし,この列に挿入するのは価格だけなので,正の整数値しかあり得ない。

 よって,この列に正しい値のみを入力していくためには,データ型の宣言だけでは不十分で,「この列は0よりも大きな整数値が挿入される」という条件も必要になる。この条件を与えるオプションが,制約だ。

 制約を使わずに,アプリケーション側でデータベースへの不正な値の挿入をチェックする仕組みを用意することも可能だ。しかし制約も用いれば,アプリケーション側とデータベース側で二重にチェックが行える。

 また,うっかりアプリケーション側で制限することを忘れても,データベース側で間違った値の入力を排除できるわけだ。

重複なしや入力不可欠などを指定

 指定した列に対して付けられる制約には,いくつかの種類がある。よく使われるのは次の4つだ。

(1)NOT NULL制約

 NOT NULL制約は,指定した列に値が必ず挿入されることを保証するものだ。


sample=> CREATE TABLE t1 ( i INTEGER NOT NULL );

のように,指定した列(ここでは「i」)の後ろに「NOT NULL」という文字を付けて,テーブルを作成する。すると,i列には値を必ず挿入しなければならなくなる。

 もしNULLを挿入する(値を入れない)と,図1のようにERRORメッセージが表示される。

図1●NOT NULL制約を付けた列に値を挿入しなかった
図1●NOT NULL制約を付けた列に値を挿入しなかった
ERRORメッセージが表示される。
[画像のクリックで拡大表示]

(2)UNIQUE制約

 UNIQUE制約は,指定した列に必ず重複しない値が挿入されることを保証するものだ。


sample=> CREATE TABLE t2 ( i INTEGER UNIQUE );

のように,テーブル作成時に指定した列(ここでも「i」)の後ろに「UNIQUE」という文字を付ける。すると,テーブルが作成されると同時に,指定列のユニーク・インデックスが作成される。このユニーク・インデックスを用いて,重複する値の挿入を禁止する*1。もし重複する値を挿入すると,2回目の挿入時でエラーとなる(図2)。

図2●UNIQUE制約を付けた列に重複する値を挿入した
図2●UNIQUE制約を付けた列に重複する値を挿入した
2回目の挿入時にエラーになる。
[画像のクリックで拡大表示]

 インデックスはデータベースの検索を高速化する仕組みである。詳しくは,別掲記事「インデックスの作成方法」を見てほしい。

(3)PRIMARY KEY制約

 PRIMARY KEY制約は,NOT NULL制約とUNIQUE制約が1つになったようなもので,「値の重複がなく,なおかつ値が必ず挿入される」という制約である。データベースの「主キー」(それぞれのレコードを識別する情報)として利用する列に付与するものだ。PRIMARY KEY制約は,テーブルに対して1つしか指定できない。ただし複数の列をまとめて,1つのPRIMARY KEY制約を付与できる。

 図3の1行目のように,指定した列(ここでも「i」)の後ろに「PRIMARY KEY」という文字を付ける。複数列の場合には,すべての列を定義した後に,「PRIMARY KEY」という文字と,かっこ内に指定する列をカンマで区切って付与する(図3の2行目)。

図3●PRIMARY KEY制約を用いてテーブルを作成
図3●PRIMARY KEY制約を用いてテーブルを作成
指定した列の後ろに「PRIMARY KEY」という文字を付ける。
[画像のクリックで拡大表示]

 PRIMARY KEY制約を付けて,テーブルを作成したときもユニーク・インデックスが自動作成され,それを用いて挿入される値の重複チェックが行われる。

(4)CHECK制約

 CHECK制約は,指定した条件を満たすもののみデータ挿入を許すものだ。例えば,


sample=> CREATE TABLE t5 ( price INTEGER CHECK( price > 0 ) );

のように,指定した列(ここでも「price」)の後ろに,「CHECK」という文字と,かっこ内に適用する条件を記述する。データの挿入時にこのチェックが働き,条件に一致する場合のみデータが挿入される。例では,price列に0より大きい4バイトの整数値しか挿入できないようにしている。

 もし負の値を挿入するとエラーとなる(図4)。

図4●0より大きい値を挿入する制約を付けた列に負の値を挿入した
図4●0より大きい値を挿入する制約を付けた列に負の値を挿入した
エラー・メッセージが表示される。
[画像のクリックで拡大表示]

■訂正
「(4)CHECK制約」を解説した部分に誤りがありました。公開時の「例では,price列に0より大きい4ビットの整数値しか挿入できないようにしている。」を「例では,price列に0より大きい4バイトの整数値しか挿入できないようにしている。」に訂正いたしました。 [2007/10/18 18:06]