「MySQLでテーブルを作るにはどうすればいいの?」
そんな疑問を持った方は多いのではないでしょうか。
MySQLにおいて、テーブルはデータを保存するための箱のようなもの。
その箱を作るための命令が、CREATE TABLE
文です。
この記事では、初心者の方でも迷わずにテーブル作成ができるように、CREATE TABLE
文の基本から応用までを、図や例を使いながらわかりやすく解説していきます。
CREATE TABLE文の基本を理解しよう

最もシンプルな書き方
CREATE TABLE テーブル名 (
カラム名1 データ型,
カラム名2 データ型,
カラム名3 データ型
);
実際の例で理解しよう
ユーザー情報を保存するテーブル
CREATE TABLE users (
id INT,
name VARCHAR(100),
email VARCHAR(255)
);
この例では:
users
:テーブル名(ユーザー情報を入れる箱)id
:ユーザーのID番号(整数)name
:ユーザーの名前(最大100文字の文字列)email
:メールアドレス(最大255文字の文字列)
テーブルのイメージ
作成されるテーブルは、このような形になります:
id | name | |
---|---|---|
(空) | (空) | (空) |
データを入れると:
id | name | |
---|---|---|
1 | 田中太郎 | tanaka@example.com |
2 | 佐藤花子 | sato@example.com |
重要な用語の解説
テーブル名
- データを保存する箱の名前
- 英数字とアンダースコアが使える
- わかりやすい名前をつける(例:
users
、products
、orders
)
カラム名
- 箱の中に入るデータの項目名(列)
- どんな情報を保存するかを表す名前
- 例:
id
、name
、email
、created_at
データ型
- そのカラムに保存できるデータの種類
- 例:
INT
(整数)、VARCHAR(n)
(文字列)、DATE
(日付)
よく使うデータ型を覚えよう

数値型
INT:整数を保存
age INT -- 年齢:25、30、45など
DECIMAL(全体桁数, 小数桁数):正確な小数を保存
price DECIMAL(10,2) -- 価格:1999.99、150.50など
BIGINT:大きな整数を保存
user_count BIGINT -- ユーザー数:1000000など
文字列型
VARCHAR(文字数):可変長の文字列
name VARCHAR(100) -- 名前:最大100文字
email VARCHAR(255) -- メール:最大255文字
TEXT:長い文字列
description TEXT -- 商品説明など長い文章
CHAR(文字数):固定長の文字列
prefecture CHAR(2) -- 都道府県コード:01、13など
日時型
DATE:日付のみ
birth_date DATE -- 誕生日:1990-05-15
DATETIME:日付と時刻
created_at DATETIME -- 作成日時:2025-06-03 14:30:00
TIMESTAMP:タイムスタンプ
updated_at TIMESTAMP -- 更新日時(自動更新される)
データ型の選び方
数値を保存する場合
- 整数 →
INT
- お金や正確な小数 →
DECIMAL
- とても大きな数 →
BIGINT
文字を保存する場合
- 短い文字(名前、タイトル) →
VARCHAR
- 長い文章 →
TEXT
- 決まった長さ(郵便番号、コード) →
CHAR
日付・時刻を保存する場合
- 日付のみ →
DATE
- 日付と時刻 →
DATETIME
- 自動更新される時刻 →
TIMESTAMP
制約(ルール)をつけてより安全なテーブルにしよう
制約とは、データの正しさを保つためのルールです。
主な制約の種類
制約名 | 意味 | 効果 |
---|---|---|
PRIMARY KEY | 主キー | 重複・NULL値を許さない、テーブルで1つだけ |
NOT NULL | 必須項目 | 空(NULL)の値を許さない |
UNIQUE | 一意性 | 重複する値を許さない |
AUTO_INCREMENT | 自動採番 | 数値が自動で1、2、3…と増加 |
DEFAULT | 初期値 | 値が指定されないときのデフォルト値 |
実際の使用例
基本的な制約付きテーブル
CREATE TABLE users (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(100) NOT NULL,
email VARCHAR(255) UNIQUE,
age INT,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
この例の説明:
id
:主キーで自動採番(1、2、3…と自動で増える)name
:必須項目(空にできない)email
:重複不可(同じメールアドレスは登録できない)age
:年齢(空でもOK)created_at
:作成日時(自動で現在時刻が入る)
制約の具体的な効果
PRIMARY KEYの効果
-- これは成功
INSERT INTO users (name, email) VALUES ('田中太郎', 'tanaka@example.com');
-- これはエラー(idが重複)
INSERT INTO users (id, name, email) VALUES (1, '佐藤花子', 'sato@example.com');
NOT NULLの効果
-- これはエラー(nameが空)
INSERT INTO users (email) VALUES ('yamada@example.com');
-- これは成功
INSERT INTO users (name, email) VALUES ('山田次郎', 'yamada@example.com');
UNIQUEの効果
-- 1回目は成功
INSERT INTO users (name, email) VALUES ('鈴木一郎', 'suzuki@example.com');
-- 2回目はエラー(emailが重複)
INSERT INTO users (name, email) VALUES ('高橋二郎', 'suzuki@example.com');
実際の業務でよく使うテーブル例

ECサイトの商品テーブル
CREATE TABLE products (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(200) NOT NULL,
description TEXT,
price DECIMAL(10,2) NOT NULL,
stock_quantity INT DEFAULT 0,
category_id INT,
is_active BOOLEAN DEFAULT TRUE,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
ブログの記事テーブル
CREATE TABLE articles (
id INT PRIMARY KEY AUTO_INCREMENT,
title VARCHAR(255) NOT NULL,
content TEXT NOT NULL,
author_id INT NOT NULL,
status ENUM('draft', 'published', 'archived') DEFAULT 'draft',
view_count INT DEFAULT 0,
published_at DATETIME,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
社員管理テーブル
CREATE TABLE employees (
id INT PRIMARY KEY AUTO_INCREMENT,
employee_code VARCHAR(10) UNIQUE NOT NULL,
first_name VARCHAR(50) NOT NULL,
last_name VARCHAR(50) NOT NULL,
email VARCHAR(255) UNIQUE NOT NULL,
department_id INT,
position VARCHAR(100),
salary DECIMAL(10,2),
hire_date DATE NOT NULL,
birth_date DATE,
phone VARCHAR(20),
address TEXT,
is_active BOOLEAN DEFAULT TRUE,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
よくある間違いと対策
データ型の選び間違い
間違った例
CREATE TABLE users (
age VARCHAR(10), -- 年齢を文字列にしている
price VARCHAR(20), -- 価格を文字列にしている
created_at VARCHAR(50) -- 日付を文字列にしている
);
正しい例
CREATE TABLE users (
age INT, -- 年齢は整数
price DECIMAL(10,2), -- 価格は小数
created_at DATETIME -- 日付は日時型
);
なぜ間違いなのか?
- 数値として計算できない
- 日付として並び替えできない
- データサイズが無駄に大きくなる
PRIMARY KEYがない
問題のある例
CREATE TABLE users (
name VARCHAR(100),
email VARCHAR(255)
);
改善された例
CREATE TABLE users (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(100),
email VARCHAR(255)
);
なぜPRIMARY KEYが必要?
- レコードを一意に識別できる
- 更新・削除時に確実に対象を指定できる
- 他のテーブルから参照しやすい
命名規則の不統一
悪い例
CREATE TABLE UserInfo ( -- 大文字小文字が混在
ID INT, -- 大文字
UserName VARCHAR(100), -- キャメルケース
user_email VARCHAR(255), -- スネークケース
CreatedAt DATETIME -- 混在
);
良い例
CREATE TABLE user_info ( -- 全て小文字+アンダースコア
id INT, -- 小文字
user_name VARCHAR(100), -- スネークケース
user_email VARCHAR(255), -- スネークケース
created_at DATETIME -- スネークケース
);
テーブル作成時のベストプラクティス

1. 一貫した命名規則
テーブル名
- 全て小文字
- 複数形を使う(
users
、products
、orders
) - アンダースコア区切り(
user_profiles
、order_items
)
カラム名
- 全て小文字
- アンダースコア区切り(
first_name
、created_at
) - 略語は避ける(
description
をdesc
にしない)
2. 必須カラムの設定
どのテーブルにも含めるべきカラム
id INT PRIMARY KEY AUTO_INCREMENT,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
3. 適切なデータ型の選択
文字列の長さ
- 名前:
VARCHAR(100)
- メールアドレス:
VARCHAR(255)
- タイトル:
VARCHAR(255)
- 説明文:
TEXT
数値の精度
- ID:
INT
- 金額:
DECIMAL(10,2)
- 数量:
INT
- パーセンテージ:
DECIMAL(5,2)
4. 制約の適切な使用
CREATE TABLE users (
id INT PRIMARY KEY AUTO_INCREMENT, -- 主キー
email VARCHAR(255) UNIQUE NOT NULL, -- 一意かつ必須
name VARCHAR(100) NOT NULL, -- 必須
age INT CHECK (age >= 0), -- 0以上の制約
status ENUM('active', 'inactive') DEFAULT 'active', -- 選択肢と初期値
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
IF NOT EXISTSで安全にテーブル作成
基本的な使い方
CREATE TABLE IF NOT EXISTS users (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(100) NOT NULL,
email VARCHAR(255) UNIQUE
);
効果
- テーブルが既に存在する場合はエラーにならない
- スクリプトの再実行が安全にできる
実用的な例
-- データベースが存在しない場合は作成
CREATE DATABASE IF NOT EXISTS my_app;
-- データベースを選択
USE my_app;
-- テーブルが存在しない場合のみ作成
CREATE TABLE IF NOT EXISTS users (
id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(50) UNIQUE NOT NULL,
email VARCHAR(255) UNIQUE NOT NULL,
password_hash VARCHAR(255) NOT NULL,
full_name VARCHAR(100),
avatar_url VARCHAR(500),
is_active BOOLEAN DEFAULT TRUE,
last_login_at DATETIME,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
実践演習:実際にテーブルを作ってみよう
演習1:図書館管理システム
要件
- 本の情報を管理したい
- 必要な項目:ID、タイトル、著者、出版社、出版年、ISBN、貸出状況
解答例
CREATE TABLE books (
id INT PRIMARY KEY AUTO_INCREMENT,
title VARCHAR(255) NOT NULL,
author VARCHAR(100) NOT NULL,
publisher VARCHAR(100),
published_year INT,
isbn VARCHAR(13) UNIQUE,
is_borrowed BOOLEAN DEFAULT FALSE,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
演習2:レストラン予約システム
要件
- 予約情報を管理したい
- 必要な項目:ID、顧客名、電話番号、予約日時、人数、特記事項、ステータス
解答例
CREATE TABLE reservations (
id INT PRIMARY KEY AUTO_INCREMENT,
customer_name VARCHAR(100) NOT NULL,
phone VARCHAR(20) NOT NULL,
reservation_datetime DATETIME NOT NULL,
party_size INT NOT NULL,
special_requests TEXT,
status ENUM('confirmed', 'cancelled', 'completed') DEFAULT 'confirmed',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
演習3:ECサイトの注文システム
要件
- 注文情報を管理したい
- 必要な項目:ID、顧客ID、注文日、合計金額、配送先住所、ステータス
解答例
CREATE TABLE orders (
id INT PRIMARY KEY AUTO_INCREMENT,
customer_id INT NOT NULL,
order_date DATETIME DEFAULT CURRENT_TIMESTAMP,
total_amount DECIMAL(10,2) NOT NULL,
shipping_address TEXT NOT NULL,
status ENUM('pending', 'processing', 'shipped', 'delivered', 'cancelled') DEFAULT 'pending',
notes TEXT,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
エラーが出たときの対処法

よくあるエラーメッセージ
1. Syntax error
ERROR 1064 (42000): You have an error in your SQL syntax
原因と対処
- カンマの付け忘れ、括弧の閉じ忘れ
- SQL文を見直して構文をチェック
2. Duplicate column name
ERROR 1060 (42S21): Duplicate column name 'id'
原因と対処
- 同じカラム名を重複して定義している
- カラム名を確認して重複を削除
3. Table already exists
ERROR 1050 (42S01): Table 'users' already exists
原因と対処
- 同じ名前のテーブルが既に存在
IF NOT EXISTS
を使うか、別のテーブル名にする
次のステップ:さらに高度なテーブル設計
外部キー制約
CREATE TABLE orders (
id INT PRIMARY KEY AUTO_INCREMENT,
customer_id INT,
product_id INT,
quantity INT NOT NULL,
FOREIGN KEY (customer_id) REFERENCES customers(id),
FOREIGN KEY (product_id) REFERENCES products(id)
);
インデックスの追加
CREATE TABLE users (
id INT PRIMARY KEY AUTO_INCREMENT,
email VARCHAR(255) UNIQUE,
name VARCHAR(100),
created_at DATETIME,
INDEX idx_name (name),
INDEX idx_created_at (created_at)
);
複合主キー
CREATE TABLE user_roles (
user_id INT,
role_id INT,
assigned_at DATETIME DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (user_id, role_id)
);
まとめ
MySQLのCREATE TABLE
文は、データベース設計の出発点です。この記事で学んだポイントを整理しましょう。
重要なポイント
- 基本構文:
CREATE TABLE テーブル名 (カラム名 データ型, ...)
- データ型選択:用途に応じて適切な型を選ぶ
- 制約の活用:PRIMARY KEY、NOT NULL、UNIQUEで データの整合性を保つ
- 命名規則:一貫した命名でメンテナンス性を向上
- IF NOT EXISTS:安全なテーブル作成
ベストプラクティス
- 必ずPRIMARY KEYを設定する
- created_atとupdated_atを含める
- 適切な制約でデータの品質を保つ
- わかりやすい命名を心がける
コメント