CodeGym /コース /SQL SELF /第三正規形 (3NF) の原則

第三正規形 (3NF) の原則

SQL SELF
レベル 25 , レッスン 3
使用可能

第三正規形 (3NF) は、データをさらにきれいに整理するためのステップだよ。ざっくり言うと、テーブルが3NFになってるのは、次の条件を満たしてるとき:

  1. すでに第二正規形 (2NF)になってる。
  2. すべての非キー属性が主キーだけに依存してること(他のものには依存しない、つまり推移的な依存関係はなし!)。

つまり、3NFは「テーブルのすべてのデータが直接主キーとだけつながってて、他の非キー属性には依存しない」ってことを求めてるんだ。

推移的な依存関係っていうのは、属性Aが属性Bに依存してて、Bが属性Cに依存してる、みたいな依存のチェーンができてる状態(A → B → C)。たとえば、「従業員」が「部署」に依存してて、「部署」が「場所」に依存してる場合、「従業員」は「場所」に推移的に依存してるってことになる。

3NF違反の例

たとえば、employees テーブルがあって、従業員のデータを保存してるとする:

employee_id name department department_manager
1 Otto Lin Marketing Leo Zhang
2 Alex Song Finance Maria Chi
3 Anna Ming Finance Maria Chi

ここで:

  • employee_id — 主キー。
  • departmentdepartment_manager — 非キー属性。

パッと見は問題なさそうだけど、よく見ると問題がある。department_manageremployee_id じゃなくて department に依存してるんだ。つまり、推移的な依存関係ができてる:employee_id → department → department_manager

どんな問題が起きる?

もし部署のマネージャーの名前(たとえば「Finance」)を変えたら、その部署が書かれてるすべての行を更新しなきゃいけない。一つでも更新し忘れると、データがバラバラになっちゃう。これはめんどくさいし、避けたいよね。

テーブルを3NFにする方法

推移的な依存関係をなくすために、テーブルを2つに分けるよ:1つは従業員データ、もう1つは部署データ。

employees テーブル

employee_id name department
1 Otto Lin マーケティング
2 Alex Song ファイナンス
3 Anna Ming ファイナンス

departments テーブル

department department_manager
マーケティング Leo Zhang
ファイナンス Maria Chi

これで、テーブルごとに役割がはっきりしたね:

  1. employees テーブルは従業員データを保存。
  2. departments テーブルは部署とそのマネージャーを保存。

もし部署のマネージャーが変わったら、departments テーブルの1行だけ更新すればOK。従業員のレコード全部を直す必要はないよ。

テーブルが3NF違反かどうかの見分け方

テーブルが3NFを違反してるかどうかをチェックするには:

  1. 推移的な依存関係がある?たとえば、属性Aが属性Bに依存してて、Bが属性Cに依存してる、みたいな。
  2. すべての非キー属性が主キーに直接依存してる?もし何かが他の非キー属性に依存してたら、そのテーブルは3NFじゃないよ。

実践例:ショップ

sales テーブルで販売データを管理してるとする:

sale_id product_name product_price customer_name
1 スマホ 20 000 Otto Lin
2 ノートパソコン 50 000 Alex Song
3 スマホ 20 000 Anna Ming

ここでは明らかに冗長性があるよね。商品の価格情報が販売ごとに繰り返されてる。もし価格が変わったら、すぐにデータがバラバラになっちゃう。

3NF違反を直すために、テーブルを2つに分けよう:

  1. sales テーブルは販売情報だけを保存。
  2. products テーブルは商品とその価格を保存。

sales テーブル

sale_id product_id customer_name
1 1 Otto Lin
2 2 Alex Song
3 1 Anna Ming

products テーブル

product_id product_name product_price
1 スマホ 20 000
2 ノートパソコン 50 000

これで、商品の価格が変わったら products テーブルの1行だけ直せばOK。データの整合性もバッチリ!

実践課題

じゃあ、課題だよ:こんな students_courses テーブルがあるとする:

student_id student_name course_name teacher_name
1 Otto Lin 数学 Maria Chi
2 Alex Song プログラミング Leo Zhang
1 Otto Lin プログラミング Leo Zhang

このテーブルを3NFに合うように分割してみて。ヒント:studentscoursesteachers の3つのテーブルを作って、ちゃんとつなげてみよう。

なぜ3NFを守るのが大事なの?

そもそも、なんで第三正規形 (3NF) にこだわるの? それは、マジで便利だから!テーブルが3NFになってると、データがきれいにまとまるし、余計な重複もなくなる。だから、うっかり壊しちゃうリスクも減るし、更新も楽になる。全部が1か所にまとまってるから、いろんな行をコピペして直す必要もない。

しかも、データベースの構造が柔軟になる。新しいカラムを追加したり、古いのを変えたりするのも簡単。

でも、どんな良い話にも注意点はある。正規化しすぎると、テーブルが細かくなりすぎて、JOINだらけの複雑なクエリになっちゃうこともある。場合によってはパフォーマンスが落ちることもあるから、バランスが大事。必要なところは正規化して、ちょっとぐらい冗長でもOKなところは気にしすぎなくていいよ。

これからもっと深く学んでいこう。テーブル同士のつながりをちゃんと設計して、使いやすくて信頼できるデータベースを作ろう!さあ、最高のDBデザインを目指して進もう!

コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION