【ITニュース解説】Database Normalization in SQL — 1NF, 2NF, and 3NF Explained (Student–Course Case Study)
2025年10月04日に「Dev.to」が公開したITニュース「Database Normalization in SQL — 1NF, 2NF, and 3NF Explained (Student–Course Case Study)」について初心者にもわかりやすく解説しています。
ITニュース概要
データベース正規化は、データの重複を減らし、整合性を保つための重要な設計手法だ。記事では、1NF、2NF、3NFの3ステップを学生とコースの具体例で解説し、データの登録・更新・削除時の問題を解決する。これにより、効率的で保守しやすいデータベースを作る方法を学ぶ。
ITニュース解説
データベースの正規化は、データ管理の効率性と信頼性を高める上で非常に重要な考え方だ。データが重複なく、整理された形で保存されることを保証し、データの正確さを保つ。もしデータベースが適切に設計されていないと、後々さまざまな問題が発生する可能性がある。ここでは、データベースの設計における基本的な正規化のルールである第一正規形(1NF)、第二正規形(2NF)、第三正規形(3NF)を、学生、コース、講師の情報を例にしながら説明する。
最初に、ある大学の学生、受講しているコース、そしてそのコースを担当する講師の情報を、一つの大きなテーブルにまとめた状況を想像してみよう。このテーブルは、一見すると全ての情報が一箇所に集まっていて便利に見えるかもしれない。しかし、このような設計では、いくつかの深刻な問題が生じる可能性がある。 例えば、『挿入の異常』という問題がある。これは、まだどの学生も受講していない新しいコースの情報をデータベースに追加しようとしても、そのコースを受講する学生がいない限り、情報を登録できない、という状況を指す。 次に、『更新の異常』だ。もし講師の電話番号が変わった場合、その講師が担当するコースを受講している学生の全ての行について、手作業で電話番号を更新する必要がある。もし一つでも更新し忘れると、データベース内でデータの不整合が発生してしまう。 そして、『削除の異常』も大きな問題だ。もしある学生が特定のコースから退学した場合、その学生とそのコースの情報をテーブルから削除することになる。ところが、もしそのコースをその学生しか受講していなかったり、その講師の情報をそのコースでしか持っていなかったりすると、学生の情報を消すことによって、コースや講師に関する重要な情報まで失われてしまう可能性があるのだ。 これらの問題を解決し、データベースをより堅牢にするために『正規化』という手順を踏んでいく。正規化は、データベースの構造を段階的に改善していくプロセスだ。
最初のステップは『第一正規形(1NF)』への変換だ。1NFのルールは、データベースの各列(属性)には単一の、それ以上分解できない値(原子値)のみが含まれていなければならない、というものだ。例えば、一つのセルに複数の電話番号や、複数の科目のリストが入っているような状態は1NFに違反する。先ほどの学生、コース、講師の情報をまとめたテーブルでは、各セルに単一の値が入っているので、形式的には既に1NFを満たしていると言える。しかし、この状態ではまだコース名や講師の詳細といった情報が、同じコースを受講する学生の行ごとに何度も繰り返されており、データの重複(冗長性)が多く残っている状態だ。
次に進むのは『第二正規形(2NF)』だ。2NFのルールは、テーブルに複合主キー(複数の列を組み合わせて一つのレコードを一意に識別するキー)がある場合、主キーではない全ての列は、主キー全体に依存しなければならない、というものだ。つまり、主キーの一部にだけ依存する非主キー属性があってはならない。これを『部分関数従属の排除』と呼ぶ。 先ほどのテーブルでは、学生IDとコースIDの組み合わせが、特定の学生が特定のコースを受講していることを一意に特定する複合主キーになり得る。しかし、コース名、講師名、講師の電話番号といった情報は、学生IDとは関係なく、コースIDのみに依存している。これが部分関数従属であり、2NFのルールに違反している。 この問題を解決するため、テーブルを役割ごとに分割する。具体的には、『学生情報だけを持つテーブル』、『コース情報と講師の詳細情報を持つテーブル』、そして『どの学生がどのコースを受講しているかを記録するテーブル』の三つに分けるのだ。 学生テーブルには学生ID、学生名といった学生自身の情報だけを格納する。コーステーブルにはコースID、コース名、そしてそのコースを担当する講師名と電話番号を格納する。そして、受講テーブルは、学生IDとコースIDを組み合わせた情報だけを持つ。 この分割により、各テーブルのデータはそれぞれの主キー全体に依存するようになり、学生とコースの間での情報の重複は大幅に減る。しかし、この段階でもまだ、講師とその電話番号の情報が、もし同じ講師が複数のコースを担当していれば、コーステーブル内で重複している可能性がある。
最後に、より高度な『第三正規形(3NF)』へ進む。3NFのルールは、非主キー属性が、他の非主キー属性に依存してはならない、というものだ。これを『推移的関数従属の排除』と呼ぶ。 2NF化したコーステーブルを考えると、コースIDが主キーであり、講師名と講師の電話番号は非主キー属性だ。この中で、講師の電話番号は、直接コースIDに依存しているのではなく、講師名に依存している。つまり『コースID』→『講師名』→『講師の電話番号』という間接的な依存関係が存在する。これが推移的関数従属であり、3NFに違反している状態だ。 この問題を解消するために、講師名と講師の電話番号をさらに独立した『講師テーブル』として分離する。講師テーブルには、講師を識別するための講師ID、講師名、そして講師の電話番号だけを格納する。 そして、コーステーブルは、講師の詳細情報を直接持つ代わりに、講師IDを外部キーとして講師テーブルを参照するように変更する。これにより、コーステーブルはコースIDとコース名、そして担当講師の講師IDだけを持つシンプルな構造になる。 この3NFへの正規化によって、講師の電話番号が変更された場合でも、講師テーブルの一箇所だけを更新すればよくなり、データの更新がはるかに簡単で安全になる。また、講師の情報は講師テーブルに集約されるため、冗長性も完全に排除される。各列がそのテーブルの主キーにのみ依存する状態となり、データの整合性が最高レベルで保たれるのだ。
このように正規化された複数のテーブルは、それぞれが特定の情報を効率的に保持している。元の形のように全ての情報を一度に取得したい場合は、『JOIN』というデータベース操作を用いて、テーブル間の関連性に基づいて情報を結合することで、必要なデータを全て取得できる。この結合操作によって得られる結果は、元の冗長なテーブルが持っていた情報と全く同じだが、その裏側にあるデータ構造ははるかに効率的で整理されたものになっている。 正規化は単なる理論上の概念ではなく、実践的なデータベース設計の原則だ。1NF、2NF、3NFといった段階を経てテーブルを分割し、整理することで、データの重複をなくし、挿入、更新、削除の際に発生する可能性のある問題を未然に防ぎ、データベース全体の保守性を高めることができる。結果として、より効率的で、拡張性があり、エラーの少ないデータベースを構築することにつながるのだ。