CREATE DATABASE と CREATE TABLE
このレッスンで分かること
- DDL (
CREATE等) は構造を作る、DML (SELECT等) は中身を扱うCREATE TABLE 名前 (列名 型 制約, ...)の形で作ります- 冪等性が必要なら
IF NOT EXISTSを付けます
CREATE DATABASE と CREATE TABLE とは
データベースとテーブルの作成を、ターミナルで実際に操作しながら学びます。本レッスンでは、CREATE DATABASE と CREATE TABLE の基本から実際の使いどころまでを整理し、現場で迷わず使える形に落とし込みます。
なぜ重要か
ここまでは既にあるテーブルからデータを取り出す側に立ってきましたが、実務ではテーブルそのものを「設計して用意する」工程が必ず先にあります。アプリのバックエンド担当に「ユーザ情報を保存したいから受け取り口を作って」と頼まれた時、最初の一手は CREATE DATABASE でアプリ専用の入れ物を作り、その中に CREATE TABLE でデータの型を定義することです。テーブル設計を雑にすると、後から ALTER TABLE で型を直したり、データを移し替えたりと、コストの大きな作業が連鎖します。だからこそ最初の CREATE 文を丁寧に書ける力は、SQL を「読む」から「設計する」フェーズに進む最初の関門になります。
DDL と DML
SQL の命令文は大きく次の 2 系統に分かれます。
- DDL (Data Definition Language) — テーブルの構造を作る・変える
CREATEALTERDROPTRUNCATEなど - DML (Data Manipulation Language) — テーブルの中身を出し入れする
SELECTINSERTUPDATEDELETEなど
| 系統 | 代表的な命令 | 目的 |
|---|---|---|
| DDL | CREATE ALTER DROP | 構造の定義・変更 |
| DML | SELECT INSERT UPDATE DELETE | 中身の操作 |
| DCL | GRANT REVOKE | 権限の付与・剥奪 |
| TCL | BEGIN COMMIT ROLLBACK | トランザクション制御 |
この章は DDL と DML をひとつながりで学ぶ章です。最初のレッスンはその入口で、まずは CREATE 系を集中的に押さえます。SELECT / WHERE / JOIN のような「読み出し系」は前章までで一通り扱いましたので、ここからは「書き込み・設計系」の世界に足を踏み入れます。
データベース・スキーマ・テーブルの関係
本レッスンの演習環境 (PostgreSQL 互換) では、CREATE DATABASE の代わりに CREATE SCHEMA でデータの入れ物を作り、SET search_path で対象を切り替えます。MySQL / TiDB では「データベース」と「スキーマ」がほぼ同義で、CREATE DATABASE → USE という書き方になりますが、役割は同じです。本番運用では「アプリ 1 つ = データベース (スキーマ) 1 つ」の対応が一般的で、それを跨いだ JOIN は基本的に避けます。
構文の基本
SQL クエリ
-- データベース (スキーマ) を作る
CREATE SCHEMA shop_db;
-- 以降の操作を shop_db に向ける
SET search_path TO shop_db;
-- テーブルを作る
CREATE TABLE users (
id INT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
email VARCHAR(255),
created_at TIMESTAMP
);CREATE TABLE の中身は「列名 型 制約」を 1 行ずつカンマ区切りで並べたものです。最後の列の後ろに余分なカンマを置くと文法エラーになる点に注意してください。
CREATE 文の処理フロー
図の流れを順序リストで書き直すと、次の通りです。
CREATE SCHEMA(MySQL/TiDB ならCREATE DATABASE) で器を作るSET search_path(MySQL/TiDB ならUSE) で対象を切り替えるCREATE TABLEを発行する- DBMS が列定義と制約を解釈する
- ストレージにメタ情報を書き込む
- これで
INSERTを受け付けられる状態になる
テーブルは「列の型と並び」というメタ情報だけが先に作られて、行はまだ 0 行です。続く INSERT 文で初めて中身が入ります。
代表例
ユーザ一覧と注文一覧という、よくある 2 つのテーブルを作る例です。
SQL クエリ
CREATE TABLE users (
id INT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
email VARCHAR(255) NOT NULL,
created_at TIMESTAMP NOT NULL
);
CREATE TABLE orders (
id INT PRIMARY KEY,
user_id INT NOT NULL,
total_amount INT NOT NULL,
ordered_at TIMESTAMP NOT NULL
);users.id と orders.id がそれぞれの主キーで、orders.user_id で users を参照する設計です。テーブルを作った直後は両方とも空なので、SELECT * FROM users; を実行しても 0 行が返ります。
IF NOT EXISTS で安全に書く
既に同名のテーブルが存在すると CREATE は失敗します。シードスクリプトや CI で何度も流す場合は IF NOT EXISTS を付けて冪等にしておくと安心です。
SQL クエリ
CREATE TABLE IF NOT EXISTS users (
id INT PRIMARY KEY,
name VARCHAR(100) NOT NULL
);テーブル名・列名は小文字スネークケース (例
created_at) が一般的です。MySQL/TiDB は OS によっては大文字小文字を区別するので、慣習に揃えると後々のトラブルが減ります。テーブル名は複数形 (users,orders)、列名は単数形にするチームが多いです。
アプリ開発では生の CREATE TABLE を書く機会は少なく、
drizzle-kitやprisma migrateのようなマイグレーションツールが SQL を自動生成します。それでも生成された SQL を読んで意図を確認するスキルは必要で、その下地が本レッスンです。
CREATE TABLEを流す前にSET search_path(MySQL/TiDB ならUSE データベース名) を忘れると、デフォルトのスキーマに余計なテーブルができてしまいます。スクリプト先頭で必ず対象を切り替えましょう。
ここまでの要点
DDL は構造、DML は中身。CREATE SCHEMA (MySQL/TiDB は CREATE DATABASE) → search_path 切替 (MySQL/TiDB は USE) → CREATE TABLE の順。冪等性は IF NOT EXISTS。テーブル名は複数形・スネークケース。
まとめ
- DDL はテーブルの「型紙」を作る命令、DML は中身を出し入れする命令
CREATE SCHEMA(MySQL/TiDB はCREATE DATABASE) →search_path切替 (MySQL/TiDB はUSE) →CREATE TABLEの順で土台を作る- 列定義は「列名 型 制約」をカンマ区切りで並べる
- 冪等性が必要なら
IF NOT EXISTSを付ける - テーブル作成直後は 0 行、INSERT で初めて行が入る
次のレッスン
次は データ型の選び方 です。SQLにおける適切なデータ型の選択方法を、具体的な例を交えながらSQLで実践的に解説します。
事前確認 — 進む前に次の 3 つができることを確認しましょう。
- CREATE DB/TABLE の要点を自分の言葉で説明できる
- このレッスンの最小コード (または操作手順) を見ずに書ける
- 練習問題やクイズで間違えた箇所を読み直して理解した
理解度チェック (30 秒)
Q. CREATE DB/TABLE とは何か、1 文で説明してください。
A. 本文の「このレッスンで分かること」または冒頭の説明文を見直し、自分の言葉で要約できれば OK。詰まったら本レッスンの最初の H2 セクションを読み返してみましょう。
関連レッスン
テーブル構造
schema.sql
-- 既にデータベースが用意されている状態を想定。
-- 空のスキーマ。あなたが CREATE TABLE で 2 つのテーブルを作ります。
SELECT 1;期待される出力
| table_name | column_count |
|---|---|
| categories | 2 |
| products | 4 |