正規化はリレーショナル DB 設計の基本。AP 科目Aで1〜2問、科目B問6でも頻出。第3正規形と BCNF の違いまで押さえましょう。
正規化 は冗長を排除して整合性を保つテーブル設計手順。
第1正規形 (1NF) から BCNF・4NF と段階的に厳しくなります。
実務でどこまで正規化するの?
業務 DB は3NF か BCNF まで、データウェアハウス系は意図的に非正規化 (スタースキーマ) することもあるわ。
AP 科目Aは3NF と BCNF が頻出ね。
1NF・2NF・3NF・BCNF…なにが違うんですかぁ?
1NF: 各列が不可分 (繰り返しを含まない)。
2NF: 1NF かつ部分関数従属を排除。
3NF: 2NF かつ推移的関数従属を排除。
BCNF: すべての関数従属の決定子が候補キーであること、3NF より厳しい。
AP では『この表は何 NF か』『次の正規形にするための分解はどれか』が頻出。
実際にテーブルを書いて確認すると一気に身につくわよ。
受注明細を第1正規形から第3正規形へ分解する
受注明細表を「受注番号、商品番号、受注日、顧客番号、顧客名、商品名、単価、数量」とし、主キーを受注番号と商品番号の組合せとします。まず、商品番号や数量を一つのセルへ複数並べず、1行1商品にすれば第1正規形です。次に関数従属を書き出します。
- 受注番号 → 受注日、顧客番号
- 商品番号 → 商品名、単価
- 受注番号+商品番号 → 数量
- 顧客番号 → 顧客名
複合主キーの一部である受注番号だけ、商品番号だけで決まる属性は部分関数従属です。これを分離し、「受注(受注番号、受注日、顧客番号、顧客名)」「商品(商品番号、商品名、単価)」「受注明細(受注番号、商品番号、数量)」にすれば第2正規形になります。さらに受注表には、受注番号 → 顧客番号 → 顧客名という推移的関数従属があるため、「顧客(顧客番号、顧客名)」を分離すると第3正規形です。
正規形を判定する順序と分解後の確認
設問では、①候補キーを特定、②すべての関数従属を矢印で列挙、③繰返し、部分従属、推移従属の順に確認します。主キーが単一列なら部分関数従属は起こらないため、1NFなら自動的に2NFです。BCNFは、各関数従属 X → Y の決定子Xが必ず候補キーかを一つずつ確認します。
分解は従属性を消すだけでなく、元の情報を復元できる無損失分解であることが重要です。分解後の表を主キー・外部キーで自然結合し、元にない組合せが増えないかを確かめます。典型誤答は「表を小さく分ければ正規化」と考えること、候補キーではなく現在指定された主キーだけを見ること、検索速度のための非正規化を正規化の失敗とみなすことです。正規化は更新時の異常を減らす論理設計、非正規化は測定結果に基づく性能上の選択と区別します。
確認クイズ
ある表が第2正規形であるが第3正規形ではない場合、その表に存在する関数従属として正しいものはどれか。
- 部分関数従属が存在する
- 推移的関数従属が存在する
- 完全関数従属が一切存在しない
- 候補キーが複数存在する
こたえを見る
正解: 2. 推移的関数従属が存在する
2NF は『部分関数従属を排除』した状態。3NF はさらに『推移的関数従属を排除』するため、2NF だが3NF でない表には推移的関数従属が残っています (例: 主キー → 非キー属性 → 別の非キー属性)。