404 Not Found

404 Not Found


nginx

MySQLのテーブルと制約の作成に関する詳細ガイド

テーブルは、データベースにデータを格納するための基本単位です。テーブル構造を適切に設計できれば、データ管理の成功は半分達成されたも同然です。

このレッスンでは、テーブルの作成方法、制約の設定方法、およびテーブルの構造の確認方法について学びます。

100%
graph TB
    A[CREATE TABLE Element] --> B[Column Definition<br/>Field Name+Data Types]
    A --> C[Constraint Definition]
    C --> D[PRIMARY KEY Primary Key]
    C --> E[FOREIGN KEY Foreign Key]
    C --> F[UNIQUE The Only One]
    C --> G[NOT NULL Not empty]
    C --> H[DEFAULT Default value]
    C --> I[CHECK Inspection]
    A --> J[Table Options<br/>ENGINE/CHARSET/COMMENT]

1. 学習内容


2. あるECシステムにまつわる実話

(1) 課題:整理されていないデータ

あるEコマースのデータベースには、顧客情報と商品情報の両方を格納するordersテーブルのみが存在します:

注文ID 顧客名 顧客電話番号 商品名 商品価格 数量
1 アリス 13800001111 iPhone 999 2
2 アリス 13800001111 MacBook 1999 1
3 ボブ 13800002222 iPhone 999 1

質問:

(2) 標準溶液の調製法

3つのテーブルに分割し、外部キーを使ってそれらを関連付けます:

SQL
-- Customer Table
CREATE TABLE customers (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(50) NOT NULL,
    phone VARCHAR(20) UNIQUE
);

-- Product List
CREATE TABLE products (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(100) NOT NULL,
    price DECIMAL(10,2) NOT NULL
);

-- Orders Table
CREATE TABLE orders (
    id INT PRIMARY KEY AUTO_INCREMENT,
    customer_id INT NOT NULL,
    product_id INT NOT NULL,
    quantity INT DEFAULT 1,
    FOREIGN KEY (customer_id) REFERENCES customers(id),
    FOREIGN KEY (product_id) REFERENCES products(id)
);

3. CREATE TABLE の構文

(1) 完全な構文

SQL
CREATE TABLE [IF NOT EXISTS] table_name (
    column1 datatype [constraints],
    column2 datatype [constraints],
    ...
    [table_constraints]
) [ENGINE=InnoDB] [DEFAULT CHARSET=utf8mb4];

▶ 例:ユーザーテーブルの作成

SQL
CREATE TABLE IF NOT EXISTS users (
    id INT PRIMARY KEY AUTO_INCREMENT,
    username VARCHAR(50) NOT NULL UNIQUE,
    email VARCHAR(100) NOT NULL,
    password_hash VARCHAR(255) NOT NULL,
    age INT CHECK (age >= 0 AND age <= 150),
    status ENUM('active', 'inactive', 'banned') DEFAULT 'active',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='User Table';
▶ 試してみよう

出力:

TEXT
Query OK, 0 rows affected (0.02 sec)

4. 主キー制約 (PRIMARY KEY)

主キーとは、テーブル内の各行を一意に識別する列のことです。重複することはできず、NULLにすることもできません。

(1) 主キーの型

種類 説明
単一カラムの主キー 単一のフィールドを主キーとする id INT PRIMARY KEY
複合主キー 複数のフィールドを組み合わせて主キーを構成 PRIMARY KEY (order_id, product_id)
自動インクリメントの主キー 連番のIDを自動的に生成 id INT AUTO_INCREMENT PRIMARY KEY

▶ 例:主キーの使用

SQL
-- Single-column primary key
CREATE TABLE categories (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(50) NOT NULL
);

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

5. 外部キー制約 (FOREIGN KEY)

外部キーは、テーブル間の関係を確立し、データの整合性を確保するために使用されます。

(1) 外部キーのカスケード操作

アクション 説明
CASCADE プライマリテーブルでレコードが削除または更新されると、セカンダリテーブルでも対応するレコードが削除または更新される
SET NULL 主テーブルが削除されると、従属テーブルの外部キーはNULLに設定される
RESTRICT 外部テーブルにレコードが存在する場合、主テーブルからの削除を禁止します(デフォルト)
措置なし 「制限」と同じ

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

SQL
CREATE TABLE orders (
    id INT PRIMARY KEY AUTO_INCREMENT,
    customer_id INT,
    order_date DATE,
    FOREIGN KEY (customer_id) REFERENCES customers(id)
        ON DELETE CASCADE
        ON UPDATE CASCADE
);

-- When deleting a customer,All orders for this customer have been automatically deleted.
DELETE FROM customers WHERE id = 1;
-- orders In the table customer_id=1 Records are automatically deleted
▶ 試してみよう

6. 一意性制約 (UNIQUE)

一意性制約により、列内の値が一意であることが保証されます(ただし、NULL値は許可されます)。

▶ 例:一意性制約

SQL
CREATE TABLE users (
    id INT PRIMARY KEY,
    email VARCHAR(100) UNIQUE,        -- Single-row, unique
    username VARCHAR(50) UNIQUE,      -- Single-row, unique
    phone VARCHAR(20),
    UNIQUE KEY (phone)                -- Another way to write it
);

-- Composite Unique Constraint
CREATE TABLE user_roles (
    user_id INT,
    role_id INT,
    UNIQUE KEY (user_id, role_id)    -- The same role cannot be assigned to the same user more than once.
);
▶ 試してみよう

7. NOT NULL 制約

NULL禁止制約は、列にNULL値を格納できないようにします。

▶ 例:NULL不可制約

SQL
CREATE TABLE products (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(100) NOT NULL,       -- Product Name (Required)
    price DECIMAL(10,2) NOT NULL,     -- Price is required
    description TEXT,                  -- The description may be left blank
    category_id INT NOT NULL
);

-- Insertion Test
INSERT INTO products (name, price) VALUES ('iPhone', 999);
-- Error:category_id Cannot be NULL
-- ERROR 1048 (23000): Column 'category_id' cannot be null
▶ 試してみよう

8. デフォルト制約 (DEFAULT)

▶ 例:デフォルト値

SQL
CREATE TABLE articles (
    id INT PRIMARY KEY AUTO_INCREMENT,
    title VARCHAR(200) NOT NULL,
    status ENUM('draft', 'published', 'archived') DEFAULT 'draft',
    view_count INT DEFAULT 0,
    is_featured BOOLEAN DEFAULT FALSE,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- Omit fields with default values during insertion
INSERT INTO articles (title) VALUES ('My First Article');

-- Search
SELECT * FROM articles;
▶ 試してみよう

出力:

TEXT
+----+-------------------+--------+------------+-------------+---------------------+
| id | title             | status | view_count | is_featured | created_at          |
+----+-------------------+--------+------------+-------------+---------------------+
|  1 | My First Article  | draft  |          0 |           0 | 2026-07-03 10:00:00 |
+----+-------------------+--------+------------+-------------+---------------------+

  1. CHECK制約(MySQL 8.0以降)

CHECK制約は、列の値が指定された条件を満たしていることを保証します。

▶ 例: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 '%@%.%')
);

-- Test
INSERT INTO employees (name, age, salary, email) VALUES ('Alice', 25, 5000, 'alice@company.com');
-- Error:age Not satisfied CHECK Conditions
INSERT INTO employees (name, age, salary, email) VALUES ('Bob', 15, 3000, 'bob@company.com');
-- ERROR 3819: Check constraint 'employees_chk_1' is violated.
▶ 試してみよう

10. テーブル構造の表示

▶ 例:テーブル情報の表示

SQL
-- View all tables in the current database
SHOW TABLES;

-- View Table Structure
DESCRIBE users;
-- Or
DESC users;

-- View the statement used to create the table
SHOW CREATE TABLE users\G

-- View the table's column information
SHOW COLUMNS FROM users;
▶ 試してみよう

出力:

TEXT
+----------------+--------------+------+-----+-------------------+----------------+
| Field          | Type         | Null | Key | Default           | Extra          |
+----------------+--------------+------+-----+-------------------+----------------+
| id             | int          | NO   | PRI | NULL              | auto_increment |
| username       | varchar(50)  | NO   | UNI | NULL              |                |
| email          | varchar(100) | NO   |     | NULL              |                |
| password_hash  | varchar(255) | NO   |     | NULL              |                |
| age            | int          | YES  |     | NULL              |                |
| status         | enum(...)    | YES  |     | active            |                |
| created_at     | timestamp    | YES  |     | CURRENT_TIMESTAMP |                |
| updated_at     | timestamp    | YES  |     | CURRENT_TIMESTAMP |                |
+----------------+--------------+------+-----+-------------------+----------------+

❓ よくある質問

Q 主キーは自動インクリメント型のINTにするべきか、それともUUIDにするべきか?
A パフォーマンスの向上とストレージ使用量の削減のため、自動インクリメント型のINTまたはBIGINTを推奨します。UUIDは分散環境には適していますが、インデックスのパフォーマンスを低下させる可能性があります。
Q 1つのテーブルに複数のUNIQUE制約を設定できますか?
A はい。1つのテーブルに複数のUNIQUE制約を設定できますが、PRIMARY KEYは1つしか設定できません。
Q 外部キーはパフォーマンスに影響しますか?
A 若干の影響はあります(書き込みのたびに制約チェックが必要になるため)が、データの整合性を確保します。高同時実行環境では、チェックをアプリケーション層で行うことも可能です。
Q NULLと空文字列の違いは何ですか?
A NULLは「値がない」ことを意味しますが、空文字列 '' は値そのものです。NULLを = 演算子を使って比較することはできず、IS NULL を使用する必要があります。
Q テーブル名は単数形と複数形のどちらにするべきですか?
A 「レコードの集合」を示すため、複数形(users、orders)の使用をお勧めします。ただし、プロジェクト全体を通じて表記を統一するようにしてください。

📖 まとめ


📝 練習問題

  1. 基本問題(難易度 ⭐):id(自動インクリメントの主キー)、name(NULL不可)、age(CHECK 18-100)、email(一意)を含む students テーブルを作成してください。

  2. 上級演習(難易度:⭐⭐)courses テーブルと、それに関連する student_courses テーブル(多対多)を作成し、外部キー制約を設定するとともに、学生が削除された際にコース登録レコードも連鎖的に削除されるようシステムを構成してください。

  3. 課題(難易度:⭐⭐⭐):ブログシステム(ユーザー、投稿、コメント、タグ)のテーブル構造を設計してください。その際、主キー、外部キー、NULL不可制約、デフォルト値などの制約を含めてください。

Web-Tutorial.com

Web-Tutorial 技術チーム

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

100%