カテゴリ: データベース 更新日: 2025/02/24

SQLの正規化とテーブル設計を完全ガイド!初心者でもわかるデータベースの整理方法

SQLの正規化とテーブル設計
SQLの正規化とテーブル設計

新人と先輩の会話形式で理解しよう

新人

「データベース設計って、どんなことを意識すればいいんですか?」

先輩

「データベースの設計では、正規化がとても重要なんだ。データの重複を減らして、一貫性を保つためのルールなんだよ。」

新人

「正規化って何ですか?具体的にどういうメリットがあるんでしょうか?」

先輩

「いい質問だね!正規化をすることで、データの無駄をなくし、変更しやすいデータ構造を作れるんだ。具体的な例を使って説明するよ!」

1. 正規化とは?

1. 正規化とは?
1. 正規化とは?

正規化とは、データの冗長性を減らし、データの整合性を保つためにテーブルを分割するプロセスです。

正規化を行うことで、以下のようなメリットがあります。

正規化のメリット

  • データの重複を減らせる - ストレージを節約し、データの一貫性を維持できる
  • データ更新が簡単になる - 1か所を変更するだけで済むため、更新ミスが減る
  • 検索が高速化される - 不必要なデータの読み込みを減らし、クエリの処理速度が向上する

正規化のステップ

データベースの正規化には、以下のような段階があります。

  • 第1正規形(1NF) - データの「原子性」を確保する
  • 第2正規形(2NF) - 部分関数従属を排除する
  • 第3正規形(3NF) - 推移的関数従属を排除する

まずは、第1正規形(1NF)のルールについて詳しく見ていきましょう。

2. 第1正規形(1NF)のルールと適用例

2. 第1正規形(1NF)のルールと適用例
2. 第1正規形(1NF)のルールと適用例

第1正規形(1NF)のルールは、すべてのカラムが単一の値を持つことです。

つまり、1つのセルに複数のデータを入れないようにする必要があります。

1. 第1正規形のルール

  • 各カラムには単一の値しか含めない
  • データは繰り返しのグループを持たない
  • 各行を一意に識別できる主キーが必要

2. 1NFに違反しているテーブルの例

以下のテーブルは、1つのセルに複数の値(担当プロジェクト)が入っており、1NFに違反しています。

非正規化(1NF違反)の例

employee_id name projects
1田中 太郎プロジェクトA, プロジェクトB
2佐藤 花子プロジェクトC
3鈴木 一郎プロジェクトA, プロジェクトC

このままだと、プロジェクトごとに検索や更新がしにくい状態です。

3. 第1正規形に正規化する

1つのセルに複数の値を含めないように、テーブルを分割して正規化します。

正規化後のテーブル

employees(社員テーブル)
employee_id name
1田中 太郎
2佐藤 花子
3鈴木 一郎
projects(プロジェクトテーブル)
project_id project_name
101プロジェクトA
102プロジェクトB
103プロジェクトC
employee_projects(社員-プロジェクトのリレーション)
employee_id project_id
1101
1102
2103
3101
3103

このように、1つのカラムに複数の値を入れるのではなく、新しいリレーションテーブル(employee_projects)を作成して、データを正規化しました。

次のセクションでは、第2正規形(2NF)のルールと適用例について解説します。

3. 第2正規形(2NF)のルールと適用例

3. 第2正規形(2NF)のルールと適用例
3. 第2正規形(2NF)のルールと適用例

第2正規形(2NF)は、第1正規形(1NF)を満たしたうえで、主キーに完全に依存していないデータを別のテーブルに分離するルールです。

1. 第2正規形のルール

  • まず、第1正規形(1NF)を満たしていること
  • 部分関数従属(主キーの一部にしか依存しないデータ)を排除する

2. 2NFに違反しているテーブルの例

以下のテーブルでは、employee_idproject_idが複合主キーになっていますが、project_nameproject_idのみに依存しており、部分関数従属が発生しています。

非正規化(2NF違反)の例

employee_id employee_name project_id project_name
1田中 太郎101プロジェクトA
1田中 太郎102プロジェクトB
2佐藤 花子103プロジェクトC
3鈴木 一郎101プロジェクトA

このままだと、project_nameproject_idのみに依存しているため、冗長なデータが生まれます。

3. 第2正規形に正規化する

project_nameを独立したprojectsテーブルに分離し、冗長性を排除します。

employees(社員テーブル)
employee_id employee_name
1田中 太郎
2佐藤 花子
3鈴木 一郎
projects(プロジェクトテーブル)
project_id project_name
101プロジェクトA
102プロジェクトB
103プロジェクトC
employee_projects(社員-プロジェクトのリレーション)
employee_id project_id
1101
1102
2103
3101

4. 第3正規形(3NF)のルールと適用例

4. 第3正規形(3NF)のルールと適用例
4. 第3正規形(3NF)のルールと適用例

第3正規形(3NF)は、第2正規形を満たしたうえで、主キーに直接関係しないデータを分離するルールです。

1. 第3正規形のルール

  • 第2正規形(2NF)を満たしていること
  • 推移的関数従属(主キーに直接関係しないデータ)がない

2. 3NFに違反しているテーブルの例

以下のテーブルでは、department_namedepartment_idに依存しており、推移的関数従属が発生しています。

非正規化(3NF違反)の例

employee_id employee_name department_id department_name
1田中 太郎10営業部
2佐藤 花子20マーケティング部

3. 第3正規形に正規化する

department_nameを別のテーブルに分離し、冗長性を排除します。

departments(部署テーブル)
department_id department_name
10営業部
20マーケティング部
employees(社員テーブル)
employee_id employee_name department_id
1田中 太郎10
2佐藤 花子20

次のセクションでは、非正規化のメリット・デメリットについて解説します。

7. 正規化の進め方と実践的なテーブル設計の流れ

7. 正規化の進め方と実践的なテーブル設計の流れ
7. 正規化の進め方と実践的なテーブル設計の流れ

データベース設計では、適切な正規化を行うことで、データの整合性を保ち、管理しやすい構造を作ることができます。ここでは、実践的な正規化の進め方を紹介します。

1. 正規化の基本的な流れ

  • 要件定義 - どのようなデータを扱うのかを整理する
  • 第1正規形(1NF) - すべてのカラムを単一の値にする
  • 第2正規形(2NF) - 部分関数従属を排除する
  • 第3正規形(3NF) - 推移的関数従属を排除する
  • 最適化 - パフォーマンスのために非正規化やインデックスを考慮する

2. 具体的なテーブル設計の例

以下のようなデータを扱うシステムを設計するとします。

ユーザーが商品を購入するECサイトのデータ

最初に、次のようなordersテーブルを作成しました。

order_id customer_name product_name price
1田中 太郎スマートフォン80000
2佐藤 花子ノートパソコン120000
3田中 太郎ワイヤレスイヤホン15000

このままだと、customer_nameproduct_nameが重複し、データ更新がしにくい状態です。

3. 正規化を適用したテーブル構成

customers(顧客テーブル)
customer_id customer_name
1田中 太郎
2佐藤 花子
products(商品テーブル)
product_id product_name price
101スマートフォン80000
102ノートパソコン120000
103ワイヤレスイヤホン15000
orders(注文テーブル)
order_id customer_id product_id
11101
22102
31103

このように分割することで、データの一貫性を保ち、管理しやすい構造になります。

8. 正規化とパフォーマンス(インデックス・リレーション)

8. 正規化とパフォーマンス(インデックス・リレーション)
8. 正規化とパフォーマンス(インデックス・リレーション)

正規化によってデータの冗長性は減りますが、結合(JOIN)が増えることでパフォーマンスが低下することがあります。

1. インデックスを活用する

インデックスを適切に設定することで、結合時の検索パフォーマンスを向上できます。


CREATE INDEX idx_customer_id ON orders (customer_id);
CREATE INDEX idx_product_id ON orders (product_id);

2. 非正規化の適用

パフォーマンスが求められる場合、一部のデータを非正規化して冗長性を持たせることもあります。


ALTER TABLE orders ADD COLUMN product_name VARCHAR(255);
UPDATE orders o 
JOIN products p ON o.product_id = p.product_id
SET o.product_name = p.product_name;

このように、一部の情報をordersテーブルに直接持たせることで、検索の速度を向上させることができます。

9. 実践!適切なテーブル設計でデータベースを最適化する方法

9. 実践!適切なテーブル設計でデータベースを最適化する方法
9. 実践!適切なテーブル設計でデータベースを最適化する方法

最後に、実際のシステム開発でよくある設計ミスと、それを防ぐ方法を紹介します。

1. よくある設計ミス

  • テーブルが大きくなりすぎる → データを適切に分割する
  • 不要なデータを持たせすぎる → 本当に必要なカラムだけを設計する
  • インデックスの設定が不適切 → 適切なインデックスを設定する

2. 最適なテーブル設計のポイント

以下のポイントを意識すると、データベースのパフォーマンスが向上します。

  • データの整合性を保ちつつ、最小限のカラムにする
  • 適切なリレーションを設定し、外部キー制約を活用する
  • インデックスを適切に設定し、検索を最適化する
  • 必要に応じて非正規化を行い、パフォーマンスを向上させる

正規化を適切に行い、パフォーマンスを考慮したテーブル設計をすることで、効率的なデータベースを構築できます。

コメント
コメント投稿は、ログインしてください

まだ口コミはありません。

カテゴリの一覧へ
新着記事
Java ServletのdoGet()メソッドとは?初心者でもわかる役割と使い方を完全解説
Spring Bootのプロジェクト構成をやさしく理解しよう
起動エラーが出たときの基本的な対処法
Java の else if を使って複数の条件を分けよう
人気記事
No.1
Java&Spring記事人気No1
SQLのビュー(VIEW)を完全ガイド!初心者でもわかる仮想テーブルの使い方
No.2
Java&Spring記事人気No2
SQLのロック(LOCK)を完全ガイド!初心者でもわかるデータの整合性の守り方
No.3
Java&Spring記事人気No3
DB接続失敗やSQLエラーの表示と対策を完全解説!初心者でもわかるSpringのエラーハンドリング
No.4
Java&Spring記事人気No4
Java の new キーワードとは?初心者でもわかるオブジェクト生成のしくみ