404 Not Found

404 Not Found


nginx

MySQLの制約条件とデータ整合性に関する詳細な解説

制約はデータの整合性を守る守護者であり、不適切なデータがデータベースに流入するのを防ぎます。

このレッスンでは、すべての制約の種類とその管理について、体系的に概説します。

100%
graph TB
    A[MySQL Constraints] --> B[PRIMARY KEY<br/>Primary Key Constraint]
    A --> C[FOREIGN KEY<br/>Foreign Key Constraints]
    A --> D[UNIQUE<br/>Unique Constraint]
    A --> E[NOT NULL<br/>Non-empty constraint]
    A --> F[CHECK<br/>Check Constraints]
    C --> C1[CASCADE]
    C --> C2[SET NULL]
    C --> C3[RESTRICT]

1. 学習内容


2. 実話

(1) 課題:不正確なデータが至る所に存在する

注文システムの稼働から6か月後、データの質は憂慮すべき状態だった。金額がマイナスの注文や、顧客と紐づいていない「ゴースト注文」、1つのユーザー名で5つのアカウントが登録されているケースなどが確認された。開発チームはアプリケーション層での検証機能の実装を試みたが、フロントエンドとバックエンドのコードがシステムのあちこちに分散していたため、常に抜け穴が生じていた。あるプロモーションキャンペーン中、ハッカーがフロントエンドの検証を迂回してマイナス金額の注文を送信し、その結果、直接的な金銭的損失が発生した。

(2) 制約付き問題を解く方法

データベースレベルでのデータ整合性の確保――PRIMARY KEYは一意性を保証し、FOREIGN KEYは関連性を保証し、CHECKは有効な範囲を保証し、UNIQUEは重複がないことを保証します。

ディメンション アプリケーションレベルの検証 データベースの制約
保護範囲 このアプリのみ すべての接続元
迂回可能性 フロントエンド/APIを迂回可能 迂回不可
保守コスト 複数の場所に分散 テーブル定義に一元化
データセキュリティ 最高

3. 5つの制限事項の概要

制約 関数 NULL 許可 重複許可
主キー 各行を一意に識別する
外部キー 他のテーブルへのリンク
一意 値の重複は許されない
NOT NULL NULLにできない
確認 基準を満たしている

4. 主キー

▶ 例:主キー制約

SQL
-- Single-column primary key
CREATE TABLE users (
    id INT PRIMARY KEY AUTO_INCREMENT,
    username VARCHAR(50)
);

-- Composite Primary Key
CREATE TABLE order_items (
    order_id INT,
    product_id INT,
    quantity INT,
    PRIMARY KEY (order_id, product_id)
);
▶ 試してみよう

5. 外部キー

▶ 例:外部キーとカスケード

SQL
CREATE TABLE orders (
    id INT PRIMARY KEY AUTO_INCREMENT,
    customer_id INT,
    amount DECIMAL(10,2),
    FOREIGN KEY (customer_id) REFERENCES customers(id)
        ON DELETE CASCADE      -- Cascade order deletions when deleting a customer
        ON UPDATE CASCADE      -- Cascade update when customer ID changes
);

-- Cascade Options
-- CASCADE: Delete Synchronously/Update
-- SET NULL: Set as NULL
-- RESTRICT: Operation Rejected(Default)
-- NO ACTION: Same as RESTRICT
▶ 試してみよう

6. UNIQUE制約

▶ 例:一意性制約

SQL
-- Single-column, unique
CREATE TABLE users (
    id INT PRIMARY KEY,
    email VARCHAR(100) UNIQUE,
    username VARCHAR(50) UNIQUE
);

-- Composite Unique
CREATE TABLE user_roles (
    user_id INT,
    role_id INT,
    UNIQUE (user_id, role_id)
);
▶ 試してみよう

7. NOT NULL 制約

▶ 例:NULL不可制約

SQL
CREATE TABLE products (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(100) NOT NULL,
    price DECIMAL(10,2) NOT NULL,
    description TEXT  -- Allow NULL
);
▶ 試してみよう

8. CHECK制約 (8.0+)

▶ 例:CHECK制約

SQL
CREATE TABLE employees (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(100) NOT NULL,
    age INT CHECK (age >= 18 AND age <= 65),
    salary DECIMAL(10,2) CHECK (salary > 0),
    email VARCHAR(100) CHECK (email LIKE '%@%.%')
);

-- Add CHECK Constraints
ALTER TABLE employees ADD CONSTRAINT chk_age CHECK (age >= 18);

-- Delete CHECK Constraints
ALTER TABLE employees DROP CHECK chk_age;
▶ 試してみよう

9. 制約管理

▶ 例:制約の追加・削除

SQL
-- Add a Primary Key
ALTER TABLE users ADD PRIMARY KEY (id);

-- Add a Foreign Key
ALTER TABLE orders ADD CONSTRAINT fk_customer 
FOREIGN KEY (customer_id) REFERENCES customers(id);

-- Add a unique constraint
ALTER TABLE users ADD UNIQUE (email);

-- Delete Foreign Key
ALTER TABLE orders DROP FOREIGN KEY fk_customer;

-- Delete the unique constraint
ALTER TABLE users DROP INDEX email;
▶ 試してみよう

❓ よくある質問

Q 外部キーはパフォーマンスに影響しますか?
A ある程度は影響します(書き込み時の制約チェックが原因ですが)、データ整合性を確保してくれます。高同時実行環境では、チェックをアプリケーション層で行うことも可能です。
Q NULL と UNIQUE の関係はどのようなものですか?
A UNIQUE では複数の NULL 値が許可されます(MySQL では、NULL != NULL です)。
Q CHECK制約で関数を使用できますか?
A MySQL 8.0以降では、CHECK制約での式の使用はサポートされていますが、サブクエリはサポートされていません。
Q CHECK制約は5.7で有効ですか?
A いいえ。MySQL 5.7では、CHECK制約は構文的には受け入れられますが、強制はされません。強制が行われるのはバージョン8.0.16以降からです。
Q 外部キーを削除しても、データは残りますか?
A はい。外部キーを削除しても、制約が解除されるだけで、データ自体は削除されません。

📖 まとめ


📝 練習問題

  1. 基本問題(難易度:⭐):完全制約を備えたユーザーテーブルを作成してください。

  2. 上級演習(難易度:⭐⭐):外部キーを作成し、カスケード削除をテストしてください。

  3. 課題(難易度:⭐⭐⭐):CHECK制約を含む製品テーブルを設計し、その制約が確実に適用されることを確認してください。

Web-Tutorial.com

Web-Tutorial 技術チーム

複数の開発者によって共同維持されているプログラミングチュートリアルプラットフォーム。各チュートリアルは専門分野の開発者が執筆・レビューしています。正確で信頼性の高いコンテンツを目指しています — 問題を見つけた場合はお知らせください。

100%