- Published on
データベースの正規化
- Authors

- Name
- Ippei Shimizu
- @ippei_111
データベース正規化の理解
データベースの正規化は、データの冗長性を減らして、データの整合性を保つためにテーブル構造を整理していくプロセスです。正規化において重要なのは、単に「ルールに従ってテーブルを分割する作業」ではなく、「データの依存関係を正しく表現する」という本質を理解することです。
なぜ、正規化が必要なのか
正規化されていないデータベースには、大きく分けて3つの問題が発生します。これらを「更新時異状」と呼びます。
1つ目は「挿入時異状」です。例えば、顧客情報と注文情報が同じテーブルで管理されてしまっているケースを考えてみます。新しい顧客を登録したいだけなのに、その顧客がまだ注文をしていないため、注文情報の列に不自然なNULL値をいれなければならない、という状況が生まれてしまいます。これは、本来独立しているはずの「顧客の存在」と「注文の存在」という2つの事実が、不適切に結合されてしまっているために起こる問題です。
2つ目は「削除時異状」です。先ほどの例で、ある顧客がの最後の注文レコードを削除した時、その顧客の情報まで一緒に消えてしまうという問題です。本来は注文だけを削除したいのに、顧客情報まで削除してしまっています。
3つ目は「更新時異状」です。同じ顧客情報が複数の注文レコードに重複して保存されている場合、顧客の住所を変更しようとすると、すべての注文レコードを更新する必要があります。もし更新漏れがあると、同じ顧客なのに異なる住所が存在するという矛盾が生じてしまいます。
段階的な正規化について理解する
正規化は段階的にすすめていきます。それぞれの段階(正規形)は、特定の種類のデータの依存関係の問題を解消します。
第1正規形(1NF)
これは、「各列に複数の値を入れてはいけない」というルールです。例えば、社員テーブルの「趣味」列に「読書、映画鑑賞、登山」というようにカンマ区切りで複数の値を入れてはいけません。理由は、このような構造では「映画鑑賞」が趣味の社員を検索するといった操作が難しくなるからです。
第2正規形(2NF)
学生IDと科目IDを複合主キーとする履修テーブルがあるとします。このテーブルに、成績とともに科目名や担当教員名を保存しているとします。ここで問題なのは、科目名や担当教員名は科目IDだけで決まる情報であり、学生IDは関係がないということです。つまり、複合主キーの一部だけに依存している情報が存在してしまっています。
これを解決するためには、科目に関する情報を別の科目テーブルに分離します。そうすることで、科目情報の重複がなくなり、科目名や担当教員を変更する際も一箇所を更新すればよくなります。
第3正規形(3NF)
社員テーブルに社員ID、社員名、部署ID、部署名がある場合を考えます。社員IDが決まれば部署IDが決まり、部署IDが決まれば部署名が決まります。つまり、「社員ID→部署ID→部署名」という推移的な依存関係があります。この場合、部署名は社員IDに直接依存しているのではなく、部署IDを経由して間接的に依存しています。
この問題を解決するには、部署情報を別の部署テーブルに分離します。社員テーブルには部署IDだけを持たせ、部署名などの詳細情報は部署テーブルで管理します。
正規化の実践的な考え方
正規化を実践する際の重要なポイントは、「各テーブルは1つの概念やエンティティを表現する」ということです。顧客テーブルは顧客について、注文テーブルは注文について、商品テーブルは商品についてのみ記述します。
また、正規化は「データの真実は一箇所にのみ存在する」という原則を実現します。同じ情報が複数の場所に存在すると、それらを同期させ続けるのはかなり難しいです。正規化により、各データは適切な一箇所にのみ保存され、必要に応じて外部キーを使って参照する構造になります。
正規化のトレードオフ
正規化には多くのメリットがありますが、完全に正規化されたデータベースでは、複雑なクエリを実行する際に多くのテーブルをJOINする必要が出てくる場合があり、パフォーマンスが低下する可能性もあります。
そのため、状況に応じては意図的に「非正規化」を行うケースもあります。例えば、集計用のサマリーテーブルを作成したり、頻繁にアクセスされる計算結果をキャッシュとして保存したりします。
実務であったケース
ポモドーロタイマー機能を開発した際に、ポモドーロ実施中に音楽を再生する機能がありました。この音楽データのIDとタイトルをポモドーロタイマーテーブルで管理しています。理由としては、この音楽情報がYouTube APIから取得したデータであり、YouTube側で削除されたりタイトルが変更される可能性があります。ポモドーロの記録は履歴のデータであり、その時点でユーザーが実際に聴いていた曲の情報をスナップショットとして保存することで、後から動画が削除されても履歴が失われないようにしています。もし、この音楽情報を正規化してマスターテーブルで管理していた場合、削除された動画や変更されたタイトルの管理が複雑になり、履歴の正確性も失われてしまう可能性がありました。