テーブルに適切な制約を設定して、データの品質を保ちましょう💪
1. NOT NULL制約: 値の入力を必須にする ✅
NOT NULL
制約は、その名の通り、カラムに NULL
(値が存在しない状態) が入ることを禁止する制約です。ユーザーIDや必須の登録情報など、「必ず値が入っていてほしい」カラムに設定します。
基本的な使い方
CREATE TABLE
文でテーブルを作成する際に、カラム定義の後ろに NOT NULL
を記述します。
CREATE TABLE users (
user_id INT PRIMARY KEY,
username VARCHAR(50) NOT NULL, -- ユーザー名は必須
email VARCHAR(100) NOT NULL, -- メールアドレスも必須
register_date DATE
);
既存のテーブルに追加する
すでに存在するテーブルのカラムに NOT NULL
制約を追加することも可能です。ただし、追加する前にそのカラムに NULL
値が含まれていないか確認する必要があります。もし NULL
が存在すると、制約の追加に失敗します。
構文はデータベース製品によって少し異なりますが、一般的には ALTER TABLE
を使います。
PostgreSQL, SQL Serverなど:
ALTER TABLE users
ALTER COLUMN register_date SET NOT NULL;
MySQL:
ALTER TABLE users
MODIFY register_date DATE NOT NULL;
なぜ使うの? 🤔
- データの完全性: 必須項目に値が必ず入ることを保証します。
- 予期せぬエラー防止: アプリケーション側で
NULL
を想定していない場合に発生するエラーを防ぎます。 - 検索の簡略化:
NULL
を考慮しない単純な条件で検索できる場合があります。(ただし、NULL
の扱いは重要です! NULLの扱いとIS NULL/IS NOT NULL も参照してください。)
NOT NULL
制約を追加する場合、対象カラムに NULL
が含まれているとエラーになります。事前に UPDATE
文などで NULL
を適切な値に置き換えるか、DEFAULT
値を設定するなどの対応が必要です。
2. UNIQUE制約: 値の重複を防ぐ 🔑
UNIQUE
制約は、指定したカラム(または複数のカラムの組み合わせ)に入る値が、テーブル内で一意(重複しない)であることを保証します。メールアドレスや商品コードなど、「他のレコードと同じ値であっては困る」カラムに使用します。
基本的な使い方
CREATE TABLE
文で、カラム定義の後ろに UNIQUE
を記述するか、テーブル定義の最後に UNIQUE (カラム名)
として指定します。
カラム定義で指定:
CREATE TABLE products (
product_id INT PRIMARY KEY,
product_code VARCHAR(20) UNIQUE, -- 商品コードはユニーク
name VARCHAR(100) NOT NULL,
price INT
);
テーブル定義の最後で指定(複数列も可能):
CREATE TABLE users (
user_id INT PRIMARY KEY,
username VARCHAR(50) NOT NULL,
email VARCHAR(100),
tel VARCHAR(15),
UNIQUE (email), -- メールアドレスはユニーク
UNIQUE (tel) -- 電話番号もユニーク (NULLは許容される場合あり)
);
-- 複数列の組み合わせでユニークにする場合
CREATE TABLE memberships (
user_id INT,
group_id INT,
role VARCHAR(20),
PRIMARY KEY (user_id, group_id),
UNIQUE (user_id, role) -- 一人のユーザーは、一つのグループ内で同じ役割を持てない
);
既存のテーブルに追加する
ALTER TABLE
を使って、既存のテーブルに UNIQUE
制約を追加できます。
ALTER TABLE products
ADD CONSTRAINT uq_product_code UNIQUE (product_code); -- 制約に名前を付けることも推奨
主キー (PRIMARY KEY) との違いは?
UNIQUE
制約と PRIMARY KEY
(主キー) 制約は、どちらも値の一意性を保証しますが、以下の違いがあります。
特徴 | UNIQUE制約 | PRIMARY KEY制約 |
---|---|---|
NULL値の許容 | 許容される(多くのDBで。ただし、NULL自体は1つまたは複数許容されるかはDBによる) | 許容されない (NOT NULL が暗黙的に適用される) |
テーブル内の数 | 複数設定可能 | 1つのみ設定可能 |
主な目的 | 特定のカラム(群)の値の重複を防ぐ | テーブル内のレコードを一意に識別する |
メールアドレスのように、「重複は困るけれど、登録時点では未入力 (NULL) も許したい」といった場合に UNIQUE
制約が役立ちます。
3. CHECK制約: 値の条件を指定する 🧐
CHECK
制約は、カラムに入力される値が特定の条件を満たしているかどうかをチェックします。条件に合わない値が INSERT
や UPDATE
されようとすると、エラーが発生します。これにより、より細かいデータの妥当性を保証できます。
基本的な使い方
CREATE TABLE
文で、カラム定義やテーブル定義の際に CHECK (条件式)
を記述します。
CREATE TABLE products (
product_id INT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
price INT CHECK (price >= 0), -- 価格は0以上
discount_rate REAL CHECK (discount_rate >= 0.0 AND discount_rate <= 1.0), -- 割引率は0.0~1.0の間
status VARCHAR(10) CHECK (status IN ('active', 'inactive', 'discontinued')) -- ステータスは指定された文字列のみ
);
-- テーブルレベルでの制約 (複数のカラムを参照可能)
CREATE TABLE orders (
order_id INT PRIMARY KEY,
order_date DATE,
ship_date DATE,
CHECK (ship_date >= order_date) -- 出荷日は注文日以降
);
既存のテーブルに追加する
ALTER TABLE
を使って、既存のテーブルに CHECK
制約を追加できます。
ALTER TABLE products
ADD CONSTRAINT chk_price CHECK (price >= 0); -- 制約に名前を付ける
どんな条件が使えるの? 💡
CHECK
制約の条件式では、以下のような演算子が利用できます。
- 比較演算子:
=
,<>
(または!=
),>
,<
,>=
,<=
- 論理演算子:
AND
,OR
,NOT
- 範囲指定:
BETWEEN
- リスト指定:
IN
- パターンマッチ:
LIKE
(一部のDB) - その他、単純な算術演算や一部の関数(DB製品による制限あり)
例えば、「年齢は18歳以上」(age >= 18)
、「性別は ‘male’ または ‘female’」(gender IN ('male', 'female'))
といった具体的なルールをデータベースレベルで強制できます。
CHECK
制約の条件式は、その行のデータだけで評価できる必要があります。基本的に他のテーブルを参照したり、結果が変わる可能性のある関数(例:NOW()
)の使用はできません。NULL
値の扱いは少し特殊です。CHECK
制約の条件式がNULL
と評価された場合(例えばNULL > 0
)、制約違反とはみなされず、NULL
の挿入や更新が許可されることがあります。
まとめ
今回は、データの整合性を保つための重要な制約、NOT NULL
, UNIQUE
, CHECK
について学びました。
- NOT NULL: 値が必須のカラムに設定し、
NULL
を禁止します。 - UNIQUE: カラム(または組み合わせ)の値の重複を防ぎます。
- CHECK: カラムの値が特定の条件を満たすことを保証します。
これらの制約を適切に使うことで、データベースに不正なデータや意図しないデータが入るのを防ぎ、アプリケーションの品質向上に繋がります。テーブルを設計する際には、各カラムにどのような制約が必要か、しっかり検討しましょう! 🎉
コメント