言語
日本語
English

Caution

お使いのブラウザはJavaScriptが無効になっております。
当サイトでは検索などの処理にJavaScriptを使用しています。
より快適にご利用頂くため、JavaScriptを有効にしたうえで当サイトを閲覧することをお勧めいたします。

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

制約(NOT NULL / UNIQUE / DEFAULT)

対応: SQL-92(1992)

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

構文

NULL値を禁止します。

列名 データ型 NOT NULL

列の値の重複を禁止します。

列名 データ型 UNIQUE

値が省略された場合のデフォルト値を設定します。

列名 データ型 DEFAULT デフォルト値

登録できる値の条件を指定します(MySQL 8.0.16以降)。

列名 データ型 CHECK (条件式)

制約に名前を付ける場合(テーブルレベル)。

CONSTRAINT 制約名 CHECK (条件式)

制約一覧

制約概要
NOT NULLNULL値の登録を禁止します。必須入力の列に設定します。
UNIQUE列内での値の重複を禁止します。メールアドレスや社員番号など一意性が必要な列に設定します。
DEFAULT 値INSERT時に値を省略した場合に自動的に設定される値を指定します。
CHECK (条件式)登録できる値を条件式で制限します(MySQL 8.0.16以降・PostgreSQL)。
CONSTRAINT 名前制約に名前を付けます。エラーメッセージに名前が表示され、原因の特定が容易になります。

サンプルコード

以下のような『employees』テーブルを作成する例で説明します。

employees employee_id name email department (empty set) Empty set

各制約を設定してテーブルを作成します。

※ 『chk_age』の CHECK 制約は、age が NULL の場合はチェックをスキップし、値がある場合のみ 18〜100 の範囲を検証します。

sample_constraints.sql
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)
);
Query OK, 0 rows affected

テーブル構造を確認します。各列に設定した制約やデフォルト値が反映されています。

sample_constraints.sql
DESCRIBE employees;
+-------------+--------------+------+-----+---------+----------------+
| Field       | Type         | Null | Key | Default | Extra          |
+-------------+--------------+------+-----+---------+----------------+
| employee_id | int          | NO   | PRI | NULL    | auto_increment |
| name        | varchar(100) | NO   |     | NULL    |                |
| email       | varchar(255) | NO   | UNI | NULL    |                |
| department  | varchar(50)  | NO   |     | 未配属  |                |
| salary      | int          | NO   |     |       0 |                |
| age         | int          | YES  |     | NULL    |                |
+-------------+--------------+------+-----+---------+----------------+
6 rows in set

UNIQUE 制約を複数列に設定します(複合ユニーク)。

sample_constraints.sql
CREATE TABLE schedule (
    room_id  INT  NOT NULL,
    date     DATE NOT NULL,
    slot     INT  NOT NULL,
    UNIQUE (room_id, date, slot)
);
Query OK, 0 rows affected

制約を満たすデータを挿入します。

sample_constraints.sql
INSERT INTO employees (name, email, department, salary, age)
VALUES ('岡部倫太郎', 'okabe@example.com', '未来ガジェット研究所', 250000, 24);
Query OK, 1 row affected (0.01 sec)
sample_constraints.sql
SELECT * FROM employees;
+-------------+------------+-------------------+----------------------+--------+------+
| employee_id | name       | email             | department           | salary | age  |
+-------------+------------+-------------------+----------------------+--------+------+
|           1 | 岡部倫太郎 | okabe@example.com | 未来ガジェット研究所 | 250000 |   24 |
+-------------+------------+-------------------+----------------------+--------+------+
1 row in set

実行結果

UNIQUE 制約に違反した INSERT を実行した場合のエラー例(MySQL)です。

-- ERROR 1062 (23000): Duplicate entry 'okabe@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・SQLite では以前からサポートされていますが、MySQL では 8.0.16 以降のサポートです。それより前のバージョンでは構文エラーにはなりませんが制約が無視されます。

-- MySQL 8.0.16以降・PostgreSQL・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 名前』で制約に名前を付ける構文も共通ですが、エラーメッセージの表示形式はデータベースごとに異なります。

概要

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

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

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

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