MySQLのテーブルと制約の作成に関する詳細ガイド
テーブルは、データベースにデータを格納するための基本単位です。テーブル構造を適切に設計できれば、データ管理の成功は半分達成されたも同然です。
このレッスンでは、テーブルの作成方法、制約の設定方法、およびテーブルの構造の確認方法について学びます。
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. 学習内容
- CREATE TABLE の完全な構文
- 主キー制約 (PRIMARY KEY)
- 外部キー制約 (FOREIGN KEY)
- 一意制約 (UNIQUE)
- NOT NULL 制約
- テーブル構造を表示する
2. あるECシステムにまつわる実話
(1) 課題:整理されていないデータ
あるEコマースのデータベースには、顧客情報と商品情報の両方を格納するordersテーブルのみが存在します:
| 注文ID | 顧客名 | 顧客電話番号 | 商品名 | 商品価格 | 数量 |
|---|---|---|---|---|---|
| 1 | アリス | 13800001111 | iPhone | 999 | 2 |
| 2 | アリス | 13800001111 | MacBook | 1999 | 1 |
| 3 | ボブ | 13800002222 | iPhone | 999 | 1 |
質問:
- アリスの電話番号は3件登録されているため、変更するには3件の登録内容を編集する必要があります。
- iPhoneの価格は2回保存しました。価格が値上がりしたら、複数の行を編集しなければなりません
- 「特定の商品がいくつ売れたか」を追跡することは不可能です。
(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 |
+----+-------------------+--------+------------+-------------+---------------------+
- 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)の使用をお勧めします。ただし、プロジェクト全体を通じて表記を統一するようにしてください。
📖 まとめ
- CREATE TABLE はテーブルを作成します。列名、データ型、および制約を指定する必要があります。
- 主キー:主キーは各行を一意に識別するものです。自動インクリメントされるINT型を使用することを推奨します。
- 外部キー テーブル間の関係を定義します。CASCADE、SET NULL、およびRESTRICTをサポートしています。
- UNIQUE ユニーク制約は、列の値が一意であることを保証します。
- NOT NULL: NOT NULL 制約は、列に NULL 値が格納されないようにします。
- DEFAULT 挿入時にデフォルト値が自動的に入力されます
- CHECK 制約(8.0以降)は、列の値が条件を満たしていることを保証します
- DESCRIBE を実行するとテーブル構造が表示されます。SHOW CREATE TABLE を実行すると完全な定義が表示されます。
📝 練習問題
-
基本問題(難易度 ⭐):id(自動インクリメントの主キー)、name(NULL不可)、age(CHECK 18-100)、email(一意)を含む
studentsテーブルを作成してください。 -
上級演習(難易度:⭐⭐):
coursesテーブルと、それに関連するstudent_coursesテーブル(多対多)を作成し、外部キー制約を設定するとともに、学生が削除された際にコース登録レコードも連鎖的に削除されるようシステムを構成してください。 -
課題(難易度:⭐⭐⭐):ブログシステム(ユーザー、投稿、コメント、タグ)のテーブル構造を設計してください。その際、主キー、外部キー、NULL不可制約、デフォルト値などの制約を含めてください。



