第三正規形 (3NF) は、データをさらにきれいに整理するためのステップだよ。ざっくり言うと、テーブルが3NFになってるのは、次の条件を満たしてるとき:
- すでに第二正規形 (2NF)になってる。
- すべての非キー属性が主キーだけに依存してること(他のものには依存しない、つまり推移的な依存関係はなし!)。
つまり、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— 主キー。departmentとdepartment_manager— 非キー属性。
パッと見は問題なさそうだけど、よく見ると問題がある。department_manager は employee_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 |
これで、テーブルごとに役割がはっきりしたね:
employeesテーブルは従業員データを保存。departmentsテーブルは部署とそのマネージャーを保存。
もし部署のマネージャーが変わったら、departments テーブルの1行だけ更新すればOK。従業員のレコード全部を直す必要はないよ。
テーブルが3NF違反かどうかの見分け方
テーブルが3NFを違反してるかどうかをチェックするには:
- 推移的な依存関係がある?たとえば、属性Aが属性Bに依存してて、Bが属性Cに依存してる、みたいな。
- すべての非キー属性が主キーに直接依存してる?もし何かが他の非キー属性に依存してたら、そのテーブルは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つに分けよう:
salesテーブルは販売情報だけを保存。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に合うように分割してみて。ヒント:students、courses、teachers の3つのテーブルを作って、ちゃんとつなげてみよう。
なぜ3NFを守るのが大事なの?
そもそも、なんで第三正規形 (3NF) にこだわるの? それは、マジで便利だから!テーブルが3NFになってると、データがきれいにまとまるし、余計な重複もなくなる。だから、うっかり壊しちゃうリスクも減るし、更新も楽になる。全部が1か所にまとまってるから、いろんな行をコピペして直す必要もない。
しかも、データベースの構造が柔軟になる。新しいカラムを追加したり、古いのを変えたりするのも簡単。
でも、どんな良い話にも注意点はある。正規化しすぎると、テーブルが細かくなりすぎて、JOINだらけの複雑なクエリになっちゃうこともある。場合によってはパフォーマンスが落ちることもあるから、バランスが大事。必要なところは正規化して、ちょっとぐらい冗長でもOKなところは気にしすぎなくていいよ。
これからもっと深く学んでいこう。テーブル同士のつながりをちゃんと設計して、使いやすくて信頼できるデータベースを作ろう!さあ、最高のDBデザインを目指して進もう!
GO TO FULL VERSION