- 推移的な依存関係がないこと:このルールが重要です。3NFのテーブルでは、任意の非主キーカラムは、他の非キーカラムを介するのではなく、単に主キーにのみ依存する必要があります。
それが実際に何を意味するのかを見てみましょう。
3NFを達成するためのテーブルの分解
テーブルを分解して3NFに達するプロセスを見ていきましょう。各ステップを説明するために、DataCampのコースからいくつかのサンプルデータを使用します。
ステップ1: 推移的依存関係の特定
まず、テーブル内の任意の属性が主キーに間接的に依存しているかどうかを調べます。一般的な基準として、属性が主キー以外の何かに依存している場合、これは推移的依存関係を示します。これは、テーブルを分割する時期が来ている可能性があることを示しています。
以下の3つのテーブルを見てください。どれに推移的依存関係がありますか?
テーブル1: コース
Course ID | Course Name | Difficulty |
---|---|---|
201 | SQL基礎 | 初級 |
202 | Python入門 | 初級 |
203 | データサイエンスの理解 | 中級 |
テーブル2: インストラクター
Instructor ID | Instructor Name | Expertise |
---|---|---|
1 | サラ・ジョンソン | データサイエンス |
2 | トム・ウィリアムズ | 機械学習 |
3 | エミリー・ブラウン | Python |
表3:登録者数
Enrollment ID | Student Name | Course ID | Course Name |
---|---|---|---|
1001 | アリス・スミス | 201 | SQL基礎 |
1002 | ボブ・グリーン | 202 | Python入門 |
1003 | チャーリー・ブルー | 201 | SQL基礎 |
答えは… 表3!
この表では、コース名はコースIDに依存していますが、登録ID(主キー)には直接依存していません。この間接的な依存関係により、コース名は推移的依存関係となります。
ステップ2:データを新しいテーブルに分ける
推移的依存関係に対処するために、テーブル1を2つのテーブルに分割します。各テーブルは直接依存するデータに焦点を当てます。
修正された登録テーブル
Enrollment ID | Student Name | Course ID |
---|---|---|
1001 | アリス・スミス | 201 |
1002 | ボブ・グリーン | 202 |
1003 | チャーリー・ブルー | 201 |
コーステーブル
現在、各テーブルにはその主キーに直接依存する情報のみが含まれています:コースIDは現在、コース名の主キーです。コーステーブル内で、登録IDは登録テーブル内の主キーです。
この分解により、テーブルは今や3NFの要件を満たし、冗長性が排除され、各テーブルが直接関連する情報のみを格納することが保証されます。
自分でデータベースを作成してみたい場合は、当社の「PostgreSQLデータベースの作成」コースをご覧ください。少し進んでいる方は、「Snowflakeにおけるデータモデリング入門」もおすすめです。エンティティ関係および次元モデリングなどの考え方がカバーされています。
第三正規形の利点と制限
では、なぜこのような努力をして3NFに到達するのでしょうか?主な特典は以下の通りです。
- データ整合性の向上: 3NFによって推移的依存関係が排除されることで、更新や削除が表全体にわたって競合や古いデータを引き起こすことが防がれます。
- 冗長性の削減: 冗長性の低減により、データベースのメンテナンスが容易になり、ストレージの使用量が削減されます。
- データ保守の簡素化: 類似情報を専用のテーブルに保持することで、冗長なエントリを追跡する必要がなくなり、レコードの更新が容易になります。
それは、3NF構造がデータの正確性をサポートする一方、追加のテーブル結合によって複雑なクエリが遅くなることがあるため、より分割されたデータにつながることがあります。速度が正規化の必要性よりも優先されるケースでは、BCNFまたは4NFがより実用的なオプションになるかもしれません。
比較:第1、第2、第3、およびBC正規形
フォームの違いを見てみましょう。
比較表:第1、第2、第3正規形
以下は、1NF、2NF、および3NFの要件を理解するのに役立つ比較表です。
BCNFは、重複する候補キーによって生じる異常をさらに排除する、3NFの「厳格な」形式です。3NFだけでは依存関係を完全に排除できない複雑なケースで特に有用です。BCNFは、非プライマリ属性が複合候補キーの一部である属性に依存する場合に適用されます。難しそうに聞こえるかもしれませんが、例を使って分解してみましょう。
現在の構造(3NFにおいて)
3NFを達成するために分解した結果、次の2つのテーブルが得られました:
登録テーブル
コーステーブル
新しい要件の紹介
さて、Coursesに新しい属性を追加します:各コースが開講される教室。この新しい属性は、BCNFが必要なシナリオを引き起こす可能性があります。
更新されたコーステーブル(3NF)
Course ID | Course Name | Classroom |
---|---|---|
201 | SQLの基礎 | ルーム101 |
202 | Python入門 | ルーム102 |
203 | データサイエンスの理解 | ルーム101 |
ここでは、コースIDが依然として主キーであり、他のすべての属性はそれに直接依存しています。しかし、各教室が一度に一つの科目しか持てないという新しいルールがあると仮定しましょう。また、コース名「SQL基礎」が異なるコースID(例えば201、204など)で提供される可能性があるとしましょう。それが異なる時間にスケジュールされている場合です。その場合、”SQL基礎“の各提供は、特定のコースIDに関わらず「101教室」で行われます。その結果、コース名もまた教室を一意に決定します。
これにより、現在2つの候補キーがあります:
- コースID
- コース名
両方の候補キーを持つことで、3NFが対処していない問題が生じました:教室はコース名に依存しており、単にコースIDには依存していません。
BCNFを適用する
この依存関係の問題を解消するために、コーステーブルを2つにさらに分解して、BCNFにより適合するようにします:
- 新しいコーステーブルは、コースIDとコース名だけを含んでいます。
- A コース詳細テーブルで、コース名と教室の関連を保存します。
これは次のようになります:
改訂されたコーステーブル(BCNF)
CourseDetailsテーブル(BCNF)
Course Name | Classroom |
---|---|
SQL基礎 | 101号室 |
Python入門 | 102号室 |
データサイエンスの理解 | 101号室 |
- コース テーブルでは、コースID が主キーであり、すべての属性がそれに完全に依存しています。
- CourseDetailsテーブルでは、Course Nameが主キーであり、ClassroomはCourse Nameにのみ依存しています。。
このセットアップは、重複する候補キーによって引き起こされる依存関係の問題を取り除き、厳密に正規化された構造を保証します。
結論
第3正規形は、データをクリーンで一貫性があり、問題のある依存関係から解放された状態に保つことを目指すデータベース設計者にとって貴重なツールです。3NFを使用することで、データの整合性が向上し、管理がスムーズになり、冗長性が減少します。3NFはほとんどの状況でうまく機能しますが、より複雑なデータベースではBCNFや4NFのような追加の形態が有益な場合があります。
この記事が役に立ったと思ったら、次のステップとして私たちのSQLアソシエイト認定を取得することを検討してください。これは、あなたのSQLとデータベース管理のスキルを検証し、潜在的な雇用主に専門性を示す素晴らしい方法です!