Caution

お使いのブラウザはJavaScriptが実行できない状態になっております。
当サイトはWebプログラミングの情報サイトの為、
JavaScriptが実行できない環境では正しいコンテンツが提供出来ません。
JavaScriptが実行可能な状態でご閲覧頂くようお願い申し上げます。

  1. トップページ
  2. SQL辞典
  3. 制約(NOT NULL / UNIQUE / DEFAULT)

制約(NOT NULL / UNIQUE / DEFAULT)

列に設定するルールのことを制約といいます。不正なデータの登録を防ぎ、データの整合性を保ちます。

構文
-- NOT NULL:NULL値を禁止します。
列名 データ型 NOT NULL

-- UNIQUE:列の値の重複を禁止します。
列名 データ型 UNIQUE

-- DEFAULT:値が省略された場合のデフォルト値を設定します。
列名 データ型 DEFAULT デフォルト値

-- CHECK:登録できる値の条件を指定します(MySQL 8.0.16以降)。
列名 データ型 CHECK (条件式)

-- 制約に名前を付ける場合(テーブルレベル)。
CONSTRAINT 制約名 CHECK (条件式)
制約一覧
制約概要
NOT NULLNULL値の登録を禁止します。必須入力の列に設定します。
UNIQUE列内での値の重複を禁止します。メールアドレスや社員番号など一意性が必要な列に設定します。
DEFAULT 値INSERT時に値を省略した場合に自動的に設定される値を指定します。
CHECK (条件式)登録できる値を条件式で制限します(MySQL 8.0.16以降・PostgreSQL)。
CONSTRAINT 名前制約に名前を付けます。エラーメッセージに名前が表示され、原因の特定が容易になります。
サンプルコード
-- 各制約を設定してテーブルを作成します。
CREATE TABLE employees (
    employee_id INT           NOT NULL AUTO_INCREMENT,
    name        VARCHAR(100)  NOT NULL,
    email       VARCHAR(255)  NOT NULL UNIQUE,
    department  VARCHAR(50)   NOT NULL DEFAULT '未配属',
    salary      INT           NOT NULL DEFAULT 0,
    age         INT,
    PRIMARY KEY (employee_id),
    CONSTRAINT chk_salary CHECK (salary >= 0),
    CONSTRAINT chk_age    CHECK (age IS NULL OR age BETWEEN 18 AND 100)
);

-- UNIQUE 制約を複数列に設定します(複合ユニーク)。
CREATE TABLE schedule (
    room_id  INT  NOT NULL,
    date     DATE NOT NULL,
    slot     INT  NOT NULL,
    UNIQUE (room_id, date, slot)
);
実行結果
-- UNIQUE 制約に違反した INSERT を実行した場合のエラー例(MySQL)
-- ERROR 1062 (23000): Duplicate entry 'tanaka@example.com' for key 'employees.email'

-- CHECK 制約に違反した INSERT を実行した場合のエラー例(MySQL 8.0.16以降)
-- ERROR 3819 (HY000): Check constraint 'chk_salary' is violated.
データベース別の書き方

『NOT NULL』『UNIQUE』『DEFAULT』は主要なデータベースで共通して使用できます。

CREATE TABLE employees (
    employee_id INT          NOT NULL,
    name        VARCHAR(100) NOT NULL,
    email       VARCHAR(255) NOT NULL UNIQUE,
    department  VARCHAR(50)  NOT NULL DEFAULT '未配属',
    salary      INT          NOT NULL DEFAULT 0
);

『CHECK』制約は PostgreSQL・Oracle・SQL Server・SQLite では以前からサポートされていますが、MySQL では 8.0.16 以降のサポートです。それより前のバージョンでは構文エラーにはなりませんが制約が無視されます。

-- MySQL 8.0.16以降・PostgreSQL・Oracle・SQL Server・SQLite(共通構文)
CREATE TABLE employees (
    salary INT NOT NULL,
    age    INT,
    CONSTRAINT chk_salary CHECK (salary >= 0),
    CONSTRAINT chk_age    CHECK (age IS NULL OR age BETWEEN 18 AND 100)
);

『CONSTRAINT 名前』で制約に名前を付ける構文も共通ですが、エラーメッセージの表示形式はデータベースごとに異なります。Oracle では制約名がエラーの特定に特に重要です。

概要

制約はデータベース側でデータの正確性を保証する仕組みです。アプリケーション側のバリデーションと二重にガードをかけることで、予期しないデータが入り込むリスクを大幅に減らせます。

『NOT NULL』と『DEFAULT』を組み合わせると、値の省略は許可しつつNULLは禁止するという設定が可能です。例えば『score INT NOT NULL DEFAULT 0』は、scoreを省略した場合に0が自動設定されます。

主キーや外部キーについては『PRIMARY KEY / FOREIGN KEY』を参照してください。テーブル作成の基本は『CREATE TABLE』で確認できます。

記事の間違いや著作権の侵害等ございましたらお手数ですがまでご連絡頂ければ幸いです。