データベース正規化とは?第1正規形から第3正規形まで実例で完全解説

 

はじめに

データベース設計において最も重要な概念の一つが「正規化」です。正規化は、データの冗長性を排除し、整合性を保ちながら効率的なデータベース構造を作る技法です。適切に正規化されたデータベースは、データの更新異常を防ぎ、ストレージの無駄遣いを避け、保守性の高いシステムを実現します。

本記事では、データベース正規化の基本概念から実践的な設計手法まで、初心者にもわかりやすく詳しく解説します。

データベース正規化とは

正規化の定義

データベース正規化とは、リレーショナルデータベースにおいて、データの冗長性(重複)を最小限に抑え、データの整合性を保つためにテーブル構造を体系的に設計する手法です。正規化により、データの更新、挿入、削除時に発生する可能性のある異常を防ぐことができます。

正規化の目的

主な目的:

  • データ冗長性の排除:同一データの重複保存を避ける
  • 更新異常の防止:一箇所の変更が他の場所に影響しないようにする
  • 挿入異常の防止:新しいデータの追加時の問題を回避
  • 削除異常の防止:データ削除時の意図しない情報損失を防ぐ
  • ストレージ効率化:無駄なデータ保存領域の削減
  • データ整合性の保証:矛盾のないデータ状態の維持

正規化が必要な理由

非正規化テーブルの問題点

正規化されていないテーブルには、以下のような深刻な問題が発生します。

更新異常(Update Anomaly) 顧客情報が複数の注文レコードに重複して保存されている場合、顧客の住所変更時にすべてのレコードを更新する必要があります。一部の更新漏れが発生すると、同一顧客に対して異なる住所情報が存在することになります。

挿入異常(Insert Anomaly) 商品情報が注文テーブルにのみ保存されている場合、注文されていない新商品の情報を登録することができません。商品マスター情報を保存するために、架空の注文レコードを作成する必要が生じます。

削除異常(Delete Anomaly) 最後の注文レコードを削除した際に、その商品に関するすべての情報(商品名、価格など)が失われてしまいます。意図していない情報の消失が発生する可能性があります。

正規化のメリット

データ整合性の向上 各データ要素が一箇所にのみ保存されるため、データの矛盾が発生しにくくなります。

保守性の向上 テーブル構造が論理的に整理されているため、システムの変更や拡張が容易になります。

ストレージ効率化 重複データが排除されるため、データベースのサイズが最適化されます。

クエリ性能の改善 適切に正規化されたテーブルは、多くの場合、クエリパフォーマンスが向上します。

第1正規形(1NF:First Normal Form)

第1正規形の定義

第1正規形は、正規化の最初のステップです。テーブルが第1正規形を満たすためには、以下の条件を満たす必要があります。

第1正規形の条件:

  • 原子性:各セル(フィールド)には分割不可能な単一の値のみが格納される
  • 重複行の排除:同一の行が存在しない
  • 列の順序に意味がない:列の順序を変更してもテーブルの意味が変わらない
  • 主キーの存在:各行を一意に識別できる主キーが定義されている

第1正規形違反の例

非正規化テーブル(問題のある例):

注文ID | 顧客名 | 商品名          | 商品価格
1      | 田中   | ノートPC,マウス | 80000,2000
2      | 佐藤   | キーボード      | 5000

この例では、「商品名」と「商品価格」のフィールドに複数の値がカンマ区切りで格納されており、原子性の原則に違反しています。

第1正規形への変換

第1正規形対応テーブル:

注文ID | 注文明細ID | 顧客名 | 商品名     | 商品価格
1      | 1         | 田中   | ノートPC   | 80000
1      | 2         | 田中   | マウス     | 2000
2      | 1         | 佐藤   | キーボード | 5000

複数の値を持っていたフィールドを分割し、各行に単一の値のみを格納するように変更しました。主キーは「注文ID + 注文明細ID」の複合キーになります。

第2正規形(2NF:Second Normal Form)

第2正規形の定義

第2正規形は、第1正規形の条件を満たしつつ、部分関数従属を排除したテーブル構造です。

第2正規形の条件:

  • 第1正規形を満たしている
  • 完全関数従属:非主キー属性が主キー全体に従属している(主キーの一部にのみ従属していない)

部分関数従属とは

部分関数従属とは、複合主キーの一部分にのみ従属している非主キー属性が存在する状態です。

第1正規形テーブルの問題点: 上記の第1正規形テーブルでは、以下の部分関数従属が存在します:

  • 「顧客名」は「注文ID」にのみ従属(注文明細IDには無関係)
  • 「商品価格」は「商品名」にのみ従属(注文IDや注文明細IDには無関係)

第2正規形への変換

注文テーブル:

注文ID | 顧客名
1      | 田中
2      | 佐藤

商品テーブル:

商品名     | 商品価格
ノートPC   | 80000
マウス     | 2000
キーボード | 5000

注文明細テーブル:

注文ID | 注文明細ID | 商品名
1      | 1         | ノートPC
1      | 2         | マウス
2      | 1         | キーボード

部分関数従属を排除し、各テーブルの非主キー属性が主キー全体に完全に従属するように分割しました。

第3正規形(3NF:Third Normal Form)

第3正規形の定義

第3正規形は、第2正規形の条件を満たしつつ、推移関数従属を排除したテーブル構造です。

第3正規形の条件:

  • 第2正規形を満たしている
  • 推移関数従属の排除:非主キー属性が他の非主キー属性に従属していない

推移関数従属とは

推移関数従属とは、主キー → 非主キー属性A → 非主キー属性Bという間接的な従属関係が存在する状態です。

第2正規形テーブルの問題例:

注文ID | 顧客名 | 顧客住所     | 顧客電話番号
1      | 田中   | 東京都渋谷区 | 03-1234-5678
2      | 佐藤   | 大阪府大阪市 | 06-9876-5432

この例では、「注文ID → 顧客名 → 顧客住所・顧客電話番号」という推移関数従属が存在します。

第3正規形への変換

注文テーブル:

注文ID | 顧客ID
1      | C001
2      | C002

顧客テーブル:

顧客ID | 顧客名 | 顧客住所     | 顧客電話番号
C001   | 田中   | 東京都渋谷区 | 03-1234-5678
C002   | 佐藤   | 大阪府大阪市 | 06-9876-5432

推移関数従属を排除し、顧客関連の情報を独立したテーブルに分離しました。

より高次の正規形

ボイス・コッド正規形(BCNF:Boyce-Codd Normal Form)

BCNFは第3正規形をより厳密にした正規形で、すべての関数従属の決定子が候補キーである必要があります。

BCNF の条件:

  • 第3正規形を満たしている
  • すべての関数従属において、決定子が候補キーになっている

第4正規形(4NF:Fourth Normal Form)

第4正規形は、多値従属性を排除した正規形です。

第4正規形の条件:

  • BCNFを満たしている
  • 多値従属性が存在しない

第5正規形(5NF:Fifth Normal Form)

第5正規形は、結合従属性を排除した正規形で、これ以上分解できない状態を表します。

第5正規形の条件:

  • 第4正規形を満たしている
  • 結合従属性が存在しない

実践的な正規化の進め方

ステップ1:要件分析

正規化を始める前に、以下の要素を明確にします。

分析項目:

  • エンティティの識別:システムで管理すべき実体の洗い出し
  • 属性の特定:各エンティティが持つ属性の定義
  • 関係性の把握:エンティティ間の関係性の明確化
  • 制約条件の確認:ビジネスルールや制約の整理

ステップ2:初期テーブル設計

要件分析の結果を基に、初期のテーブル構造を作成します。

設計のポイント:

  • すべての属性を含む包括的なテーブルから開始
  • 主キーの仮設定
  • データ型の概算決定

ステップ3:段階的正規化

第1正規形から順次、段階的に正規化を進めます。

正規化の手順:

  1. 第1正規形化:原子性の確保と主キーの設定
  2. 第2正規形化:部分関数従属の排除
  3. 第3正規形化:推移関数従属の排除
  4. 必要に応じて高次正規化:BCNF、4NF、5NFの検討

ステップ4:検証とチューニング

正規化完了後、以下の観点で検証を行います。

検証項目:

  • 整合性チェック:データの矛盾がないか
  • パフォーマンステスト:クエリ実行速度の測定
  • 運用性評価:保守・更新作業の効率性
  • ビジネス要件適合性:業務要件を満たしているか

正規化における注意点とトレードオフ

過度な正規化の問題

正規化を進めすぎることで、以下の問題が発生する可能性があります。

パフォーマンスの低下 多数のテーブル結合が必要になり、クエリの実行速度が低下する場合があります。

複雑性の増大 テーブル数の増加により、システムの理解と保守が困難になることがあります。

開発効率の低下 複雑なテーブル構造により、アプリケーション開発の生産性が低下する可能性があります。

非正規化の検討

特定の状況では、意図的に非正規化を行うことが適切な場合があります。

非正規化を検討するケース:

  • 読み取り集約的なシステム:参照性能を最優先する場合
  • データウェアハウス:分析用途でのパフォーマンス重視
  • キャッシュテーブル:計算結果の高速アクセスが必要
  • レポート用テーブル:複雑な集計処理の高速化

バランスの取り方

実際のシステム設計では、正規化のメリットとデメリットを考慮し、適切なバランスを見つけることが重要です。

判断基準:

  • システムの用途:OLTP vs OLAP
  • パフォーマンス要件:応答時間の制約
  • データ更新頻度:読み取り vs 書き込みの比率
  • 保守性の重要度:長期運用の考慮

まとめ

データベース正規化は、効率的で整合性の高いデータベース設計のための基本的かつ重要な技法です。適切な正規化により、データの冗長性を排除し、更新異常を防ぎ、保守性の高いシステムを構築できます。

正規化の要点:

第1正規形:原子性の確保と主キーの設定 第2正規形:部分関数従属の排除 第3正規形:推移関数従属の排除

実践でのポイント:

  • 段階的なアプローチで着実に進める
  • ビジネス要件との整合性を常に確認
  • パフォーマンスとのバランスを考慮
  • 必要に応じて非正規化も検討

正規化は理論的な概念ですが、実際のシステム開発では柔軟な適用が求められます。システムの特性や要件を十分に理解した上で、最適なデータベース構造を設計することが成功の鍵となります。

データベース設計者やシステム開発者にとって、正規化の理解は必須のスキルです。本記事で解説した概念と手法を参考に、より良いデータベース設計に取り組んでください。継続的な学習と実践を通じて、正規化の技術を身につけ、高品質なシステム開発を実現していきましょう。

■プロンプトだけでオリジナルアプリを開発・公開してみた!!

■AI時代の第一歩!「AI駆動開発コース」はじめました!

テックジム東京本校で先行開始。

■テックジム東京本校

「武田塾」のプログラミング版といえば「テックジム」。
講義動画なし、教科書なし。「進捗管理とコーチング」で効率学習。
より早く、より安く、しかも対面型のプログラミングスクールです。

<短期講習>5日で5万円の「Pythonミニキャンプ」開催中。

<オンライン無料>ゼロから始めるPython爆速講座