初めてのデータベース設計

第5回 制約とインデックス

この記事を読むのに必要な時間:およそ 2 分

前回は,テーブルの列のデータ型について説明しました。列のデータ型を決定すればテーブルを定義することができます。

なお,テーブルを定義する際には,列のデータ型を決するだけではなく,制約インデックスといったものも必要によって定義します。今回は,テーブルに格納するデータを限定する制約と,データベースの性能を向上させるインデックスについて説明します。

制約とは

制約とは,テーブルに格納するデータを限定する方法です。データ型によって整数であるか,文字列であるかといったデータの種類を限定することができます。しかし,それでは正数のデータのみを受け付けるとか,同じデータが重複してはいけないとかといった制限を行うことができません。

このような制約を列やテーブルに対して定義することができます。制約に違反するデータを格納しようとするとエラーとなります。

アプリケーションにおいていくらデータをチェックするとしても,最終的にデータの格納されるデータベースにおいて不整合が発生しないように,テーブルを定義する際には考えられる制約はすべて定義したほうがいいでしょう。

ここでは,第3回に登場したテーブルを例にとって制約について説明します。

検査制約

検査制約では,列のデータが論理値(真,または偽)を満足させる式として制約を定義します。

たとえば,「製品(products)」テーブルはPostgreSQLでは次のように定義することができますが,

CREATE TABLE products (
    id integer,
    name text,
    price integer
);

製品の価格は正数のみであると考えると,このテーブルの「価格(price)」列に格納するデータは0より大きな整数であるという制約として以下のように定義することができます。

CREATE TABLE products (
    id integer,
    name text,
    price integer CHECK (price > 0)
);

非NULL制約

非NULL制約は,列のデータがNULL値ではないことを保証する制約です。NULL値とは未定義のデータのことであり,非NULL制約が定義されていない列には,そのデータ型に基づくデータ以外にNULL値を格納することができます。

たとえば,製品には製品番号や製品名,価格が必ず指定されていると考えると,「製品(products)」テーブルのすべての列に対して非NULL制約を以下のように定義することができます。

CREATE TABLE products (
    id integer NOT NULL,
    name text NOT NULL,
    price integer NOT NULL CHECK (price > 0)
);

一意性制約

一意性制約は,列のデータが重複しないことを保証する制約です。なお,NULL値については重複してデータを格納したとしても,一意性制約に違反することにはなりません。

たとえば,製品番号によって製品を一意に特定できると考えると,「製品番号(id)」列には非NULL制約に加えて一意性制約を以下のように定義することができます。

  CREATE TABLE products (
      id integer UNIQUE NOT NULL,
      name text NOT NULL,
      price integer NOT NULL CHECK (price > 0)
  );

NULL値の重複が一意性制約に違反しないことは標準SQL規格に準拠していますが,SQL SeverなどのようにNULL値の重複も許容しないRDBMSがあるので注意する必要があります。

著者プロフィール

佐藤友章(さとうともあき)

SRA OSS, Inc. 日本支社 チーフエンジニア。入社以来,オープンソースデータベースPostgreSQLに関する業務に携わり,現在,PostgreSQLのサポートやコンサルティング,トレーニングの講師を務める。

URLhttp://www.sraoss.co.jp/

コメント

コメントの記入