メインコンテンツへ移動
SEMentor
データベース 約10分

リレーショナルDB の基礎と正規化

RDBの基本概念、主キー・外部キー・正規化の考え方を体系的に理解する

リレーショナルデータベースとは

**リレーショナルデータベース(RDB)は、データをテーブル(表)の形式で管理し、テーブル間の関係(リレーション)**を通じてデータを操作するデータベースです。

代表的な RDBMS(管理システム):

  • PostgreSQL — オープンソース、機能豊富
  • MySQL / MariaDB — Web システムで最も普及
  • Oracle Database — 大規模エンタープライズ向け
  • SQL Server — Microsoft 製、Windows 環境で多用
  • SQLite — 組み込み用途、ファイル 1 つで動作

キーの概念

主キー(Primary Key)

テーブル内の各行を一意に識別する列(または列の組み合わせ)。

  • NULL 不可
  • 重複不可
  • 通常は自動採番の整数(id)か UUID
CREATE TABLE users (
  id       SERIAL PRIMARY KEY,  -- 主キー(自動採番)
  email    TEXT   NOT NULL UNIQUE,
  name     TEXT   NOT NULL
);

外部キー(Foreign Key)

別テーブルの主キーを参照する列。テーブル間の関連性を定義します。

CREATE TABLE orders (
  id      SERIAL PRIMARY KEY,
  user_id INT NOT NULL REFERENCES users(id),  -- 外部キー
  amount  DECIMAL(10, 2),
  ordered_at TIMESTAMPTZ DEFAULT NOW()
);

これにより orders.user_id には users.id に存在する値しか入れられなくなります(参照整合性)。

テーブル間の関係

関係意味
1:11 行に 1 行が対応ユーザー ↔ プロファイル
1:N1 行に複数行が対応ユーザー ↔ 注文
N:N多対多商品 ↔ タグ(中間テーブルで実現)

N:N の実現例

-- 中間テーブル(関連テーブル)で多対多を表現
CREATE TABLE product_tags (
  product_id INT REFERENCES products(id),
  tag_id     INT REFERENCES tags(id),
  PRIMARY KEY (product_id, tag_id)
);

正規化

正規化は、データの重複と更新異常を防ぐためにテーブルを分割・整理する手法です。

非正規形の問題

注文テーブル(非正規化)
┌────────────────────────────────────────────────────────┐
│ order_id │ user_name │ user_email        │ item_names   │
│ 1        │ 田中      │ tanaka@email.com  │ PC, マウス   │
│ 2        │ 田中      │ tanaka@email.com  │ キーボード   │
└────────────────────────────────────────────────────────┘

問題点:

  • 田中さんのメールが変わると 2 行の更新が必要(更新異常
  • item_names が複数値で検索しにくい(第1正規形違反

第1正規形(1NF)— 繰り返しの排除

列に複数値を持たせない。1 セルに 1 値。

第2正規形(2NF)— 部分関数従属の排除

複合主キーの場合、主キーの一部にのみ依存する列を別テーブルへ移す。

第3正規形(3NF)— 推移的関数従属の排除

主キー以外の列に依存する列を別テーブルへ移す。

正規化後の設計:
users テーブル      orders テーブル      order_items テーブル
- id               - id                 - id
- name             - user_id (FK)       - order_id (FK)
- email            - ordered_at         - product_id (FK)
                                        - quantity

インデックス

インデックスは検索を高速化する索引構造です。書籍の索引と同じ原理。

-- user_idで頻繁に検索するならインデックスを張る
CREATE INDEX idx_orders_user_id ON orders(user_id);

注意:インデックスは SELECT を速くするが、INSERT/UPDATE/DELETE は遅くなる。 不必要なインデックスは貼らない。

トランザクションと ACID 特性

複数の操作をひとまとまりとして扱う仕組みがトランザクションです。

特性意味
Atomicity(原子性)全部成功か全部失敗(中途半端な状態なし)
Consistency(整合性)常にデータ制約を満たす
Isolation(独立性)複数トランザクションが干渉しない
Durability(永続性)コミット済みデータは障害後も保持
BEGIN;
  UPDATE accounts SET balance = balance - 10000 WHERE id = 1;
  UPDATE accounts SET balance = balance + 10000 WHERE id = 2;
COMMIT;  -- 両方成功したら確定
-- ROLLBACK; で両方キャンセル

まとめ

  • RDB はテーブルと主キー・外部キーでデータを管理する
  • 1:N は外部キー、N:N は中間テーブルで表現
  • 正規化でデータ重複と更新異常を防ぐ
  • インデックスは SELECT を速くするが INSERT/UPDATE に影響する
  • ACID 特性がデータの信頼性を支える

このレッスンは未完了です。

次のレッスンへ