1. 👋 はじめに
前回はAPI設計の基礎(REST・HTTPメソッド・エンドポイント設計)を学びました。
今回は データベースの基礎 を解説します!
「データはどこに保存されているの?」
Webアプリのデータはすべてデータベースに保存されています。
ユーザー情報・投稿・注文履歴…
私たちが日々使うアプリの裏側には必ずデータベースが存在します。
この記事を読めば:
- ✅ データベースとは何かがわかる
- ✅ テーブル設計の基本がわかる
- ✅ SQLの基本操作(SELECT・INSERT・UPDATE・DELETE)ができる
- ✅ テーブル間のリレーションがわかる
2. 🗄️ データベースとは?
一言で言うと
データベース(DB)とは「データを整理して保存・検索しやすくする仕組み」です。
なぜファイルではなくDBを使うのか?
📁 ファイルで管理する場合の問題:
users.txt:
田中太郎,taro@example.com,25
鈴木花子,hanako@example.com,30
...
❌ 問題点:
- 大量データの検索が遅い
- 複数の人が同時に書き込むとデータが壊れる
- 「25歳以上のユーザーだけ取得」などの複雑な条件が難しい
- データの整合性(矛盾のなさ)を保てない
✅ データベースなら:
- インデックスで高速検索
- 同時アクセスを安全に制御
- 複雑な条件での検索が簡単
- データの整合性を自動で保つ
データベースの種類
| 種類 | 特徴 | 代表例 |
|---|---|---|
| リレーショナルDB(RDB) | 表形式でデータを管理・SQLで操作 | MySQL・PostgreSQL・SQLite |
| NoSQL | 柔軟なデータ構造・大量データに強い | MongoDB・Redis・DynamoDB |
💡 このシリーズでは最も広く使われる「リレーショナルDB」を中心に解説します。
3. 📊 テーブルとは?
テーブル = Excelの表のようなもの
テーブルとは「データを行と列で管理する表」です。
Excelのシートをイメージすると理解しやすいです。
【usersテーブル】
| id | name | age | created_at | |
|---|---|---|---|---|
| 1 | 田中太郎 | taro@example.com | 25 | 2026-01-01 00:00:00 |
| 2 | 鈴木花子 | hanako@example.com | 30 | 2026-01-02 00:00:00 |
| 3 | 佐藤次郎 | jiro@example.com | 22 | 2026-01-03 00:00:00 |
| 用語 | 説明 | Excelで例えると |
|---|---|---|
| テーブル | データの集まり | シート |
| カラム(列) | データの種類(name・emailなど) | 列のヘッダー |
| レコード(行) | 1件分のデータ | 1行分のデータ |
| 主キー(PK) | 各レコードを一意に識別するID | 通し番号 |
主キー(Primary Key)とは?
主キーとは「そのレコードを他と区別するための唯一のID」です。
テーブル内で重複せず・NULLにならない値を使います。
id | name
----|----------
1 | 田中太郎 ← id=1 は世界で1人だけ
2 | 鈴木花子 ← id=2 は世界で1人だけ
2 | 佐藤次郎 ← ❌ id=2が重複!→ 主キーではNG
4. 🏗️ テーブル設計の基本
データ型を決める
カラムごとに「どんな種類のデータが入るか」を定義します。
| データ型 | 意味 | 使う場面 |
|---|---|---|
INT |
整数 | ID・年齢・数量 |
VARCHAR(n) |
最大n文字の文字列 | 名前・メールアドレス |
TEXT |
長い文字列 | 記事本文・コメント |
BOOLEAN |
真偽値(true/false) | フラグ・有効/無効 |
TIMESTAMP |
日時 | 作成日時・更新日時 |
DECIMAL(m,n) |
小数を含む数値 | 価格・税率 |
テーブル設計の実例
ECサイトを例に、必要なテーブルを設計してみましょう。
【usersテーブル】ユーザー情報
id INT 主キー・自動採番
name VARCHAR(50) ユーザー名
email VARCHAR(255) メールアドレス(一意)
password VARCHAR(255) ハッシュ化されたパスワード
created_at TIMESTAMP 登録日時
【productsテーブル】商品情報
id INT 主キー・自動採番
name VARCHAR(100) 商品名
price DECIMAL(10,2) 価格
stock INT 在庫数
created_at TIMESTAMP 登録日時
【ordersテーブル】注文情報
id INT 主キー・自動採番
user_id INT 注文したユーザーのID(外部キー)
total_price DECIMAL(10,2) 合計金額
status VARCHAR(20) 注文状況(pending/completed等)
created_at TIMESTAMP 注文日時
5. 📝 SQLの基本操作
SQLとは?
SQL(Structured Query Language)とは「データベースを操作するための言語」です。
データの取得・追加・更新・削除をSQLで行います。
① SELECT:データを取得する
-- 全カラムを取得
SELECT * FROM users;
-- 特定のカラムだけ取得
SELECT id, name, email FROM users;
-- 条件を指定して取得(WHERE句)
SELECT * FROM users WHERE age >= 25;
-- 複数の条件
SELECT * FROM users WHERE age >= 25 AND name = '田中太郎';
-- 並び替え(ORDER BY句)
SELECT * FROM users ORDER BY created_at DESC; -- 新しい順
-- 件数を制限(LIMIT句)
SELECT * FROM users LIMIT 10; -- 最初の10件だけ
-- 組み合わせて使う
SELECT id, name, email
FROM users
WHERE age >= 20
ORDER BY name ASC
LIMIT 5;
② INSERT:データを追加する
-- 新しいユーザーを追加
INSERT INTO users (name, email, age, created_at)
VALUES ('山田花子', 'yamada@example.com', 28, NOW());
-- 複数件まとめて追加
INSERT INTO users (name, email, age, created_at)
VALUES
('田中一郎', 'ichiro@example.com', 30, NOW()),
('佐藤二郎', 'jiro@example.com', 25, NOW());
③ UPDATE:データを更新する
-- ID:1のユーザーのメールアドレスを更新
UPDATE users
SET email = 'new_taro@example.com'
WHERE id = 1;
-- 複数カラムを同時に更新
UPDATE users
SET email = 'new_taro@example.com',
age = 26
WHERE id = 1;
⚠️ WHERE句を忘れると全件更新されてしまいます!
-- ❌ WHERE句なし → 全ユーザーのメールが変わる! UPDATE users SET email = 'test@example.com'; -- ✅ WHERE句あり → ID:1のユーザーだけ更新 UPDATE users SET email = 'test@example.com' WHERE id = 1;
④ DELETE:データを削除する
-- ID:1のユーザーを削除
DELETE FROM users WHERE id = 1;
-- 条件に合うレコードをまとめて削除
DELETE FROM users WHERE created_at < '2024-01-01';
⚠️ WHERE句を忘れると全件削除されてしまいます!
-- ❌ WHERE句なし → 全ユーザーが消える!(最も危険!) DELETE FROM users; -- ✅ WHERE句あり → ID:1だけ削除 DELETE FROM users WHERE id = 1;
6. 🔗 リレーション:テーブル同士の関係
リレーションとは?
リレーション(relation)とは「テーブル同士のつながり」のことです。
現実のデータは複数のテーブルにまたがっています。
外部キー(Foreign Key)
外部キーとは「別のテーブルの主キーを参照するカラム」です。
テーブル同士を結びつける「橋」の役割をします。
【usersテーブル】
| id | name |
|---|---|
| 1 | 田中太郎 |
| 2 | 鈴木花子 |
【ordersテーブル】
| id | user_id(外部キー) | total_price |
|---|---|---|
| 1 | 1 | 5,000円 |
| 2 | 1 | 3,000円 |
| 3 | 2 | 8,000円 |
id=1 : user_id=1(田中太郎)の注文
id=2 : user_id=1(田中太郎)の注文
id=3 : user_id=2(鈴木花子)の注文
外部キー(usersテーブルのidを参照)
リレーションの種類
① 1対多(One to Many)
1人のユーザーが複数の注文を持つ
users(1)──────(多)orders
田中太郎 ──→ 注文①・注文②・注文③
鈴木花子 ──→ 注文④・注文⑤
② 多対多(Many to Many)
1つの注文に複数の商品が含まれ、
1つの商品は複数の注文に含まれる
orders(多)──────(多)products
→ 中間テーブル(order_items)を使って解決!
orders ──── order_items ──── products
注文① ──→ 商品A×2個 ──→ りんご
──→ 商品B×1個 ──→ バナナ
注文② ──→ 商品A×3個 ──→ りんご
【order_items(中間テーブル)のイメージ】
| id | order_id | product_id | quantity |
|---|---|---|---|
| 1 | 1 | 1 | 2 |
| 2 | 1 | 2 | 1 |
| 3 | 2 | 1 | 3 |
(注文①に、商品1「りんご」が2個)
(注文①に、商品2「バナナ」が1個)
(注文②に、商品1「りんご」が3個)
💡 多対多は「1対多」の組み合わせでできています!
orders→order_itemsが1対多
products→order_itemsが1対多
この2つの1対多を組み合わせることで「多対多」を表現しています。
③ 1対1(One to One)
1人のユーザーが1つのプロフィールを持つ
users(1)──────(1)user_profiles
田中太郎 ──→ 田中太郎のプロフィール
JOINで複数テーブルを結合する
-- usersとordersを結合して、ユーザー名と注文金額を取得
SELECT
users.name,
orders.total_price,
orders.created_at
FROM orders
INNER JOIN users ON orders.user_id = users.id
WHERE users.id = 1;
-- 結果:
-- name | total_price | created_at
-- ---------|-------------|------------
-- 田中太郎 | 5000 | 2026-01-01
-- 田中太郎 | 3000 | 2026-01-02
| JOINの種類 | 説明 | イメージ |
|---|---|---|
INNER JOIN |
両方のテーブルに一致するレコードだけ取得 | 2つの円が重なる部分だけ |
LEFT JOIN |
左側のテーブルは全件・右側は一致するもののみ | 左の円全体+重なる部分 |
RIGHT JOIN |
右側のテーブルは全件・左側は一致するもののみ | 右の円全体+重なる部分 |
例:出席簿に例えてみると・・・・
INNER JOIN → 授業に出席した生徒だけ名簿に載せる
LEFT JOIN → 全生徒を名簿に載せる・欠席者の出席欄は空白
7. 🏛️ 正規化とは?
正規化とは「データの重複や矛盾をなくしてテーブルを整理すること」です。
ブログの投稿を例に考えてみましょう。
❌ 正規化されていないテーブル(データが重複):
posts(投稿)
id | user_name | user_email | title
---|-----------|--------------------|--------------
1 | 田中太郎 | taro@example.com | Reactの入門
2 | 田中太郎 | taro@example.com | TypeScriptの基礎
3 | 鈴木花子 | hanako@example.com | Pythonの始め方
問題点:
- 田中太郎のメールが変わると2行を修正する必要がある
- 修正漏れが起きると「同じ人なのにメールが違う」矛盾が生まれる
- ユーザー数が増えるほどデータの重複が膨らんでいく
✅ 正規化されたテーブル(データを分離):
users(ユーザー) posts(投稿)
id | name | email id | user_id | title
---|--------|------------ ---|---------|------------------
1 | 田中太郎| taro@... 1 | 1 | Reactの入門
2 | 鈴木花子| hanako@... 2 | 1 | TypeScriptの基礎
3 | 2 | Pythonの始め方
↑
外部キー(usersのidを参照)
→ 田中太郎のメールを変えるときは users テーブルの1行を直すだけ!
→ posts テーブルは user_id(番号)だけを持ち、重複がなくスッキリ
8. 🎯 まとめ
| 概念 | 一言で言うと |
|---|---|
| 🗄️ データベース | データを整理して保存・検索しやすくする仕組み |
| 📊 テーブル | データを行と列で管理する表 |
| 🔑 主キー | レコードを一意に識別するID |
| 📝 SQL | DBを操作するための言語 |
| 🔗 外部キー | 別テーブルの主キーを参照する「橋」 |
| 🔄 JOIN | 複数テーブルを結合して一度に取得する |
| 🏛️ 正規化 | データの重複・矛盾をなくして整理すること |
SQLの基本は4つだけ:
SELECT(取得)・INSERT(追加)・UPDATE(更新)・DELETE(削除)
この4つをマスターすればほとんどのDB操作ができます💪⚠️
UPDATEとDELETEには必ずWHERE句をつける習慣を!
次回は 認証・認可の基礎 を解説します!
セッション認証・JWT・パスワードの安全な扱い方を学びます🌟
💬 質問や感想があれば、コメント欄でお気軽にどうぞ!
👍 役に立ったら、いいね&ストックをお願いします!
🎓 ここまで読んでくださって、本当にありがとうございました!
🔗 シリーズ記事
- 【第一回】バックエンドとは何か・サーバーの基本
- 【第二回】API設計の基礎
- 【第三回】データベースの基礎(この記事)
- 【第四回】認証・認可の基礎(近日公開)
- 【第五回】バックエンド設計の実践(近日公開)
- 【第六回】まとめ・デプロイ・次のステップ(近日公開)