ボイス・コッド正規形(BCNF)— 3NF の強化版
候補キーが複数重なるときに 3NF が取りこぼす異常を閉じる BCNF。
BCNF とは
ボイス・コッド正規形(BCNF)は、すべての関数従属 X → Y について、X が候補キー(スーパーキー)であることを要求する正規形です。3NF よりわずかに強く、「非キー側が他の列を決めてしまう」状況を許しません。
3NF は「非キー → 非キー」の推移従属を排除しますが、候補キーが複数あって互いに重なっているときに取りこぼしが残ります。BCNF はそれを埋める強化版です。
3NF は満たすが BCNF を破る典型例
古典的な例: class (student_id, course_id, instructor)。1 人の学生が 1 つの講座を履修し、その講座には 1 人の講師がつく、という関係です。
- 候補キー:
(student_id, course_id)と(student_id, instructor)の 2 つ - 関数従属:
instructor → course_id(講師が決まれば担当講座が 1 つに決まる)
instructor は候補キーではないので、「X → Y の X は候補キーであるべき」という BCNF の条件を破ります。3NF は満たすが BCNF を破る典型状態です。
解決策: (instructor, course_id) を別テーブルに切り出して、元のテーブルは (student_id, instructor) だけにします。
なぜ 3NF では足りないのか
3NF の定義には「Y が候補キーの一部(素属性)なら許す」という例外があります。上の例では course_id がもう一方の候補キー (student_id, course_id) の構成要素なので、3NF 的には「OK」と判定されます。しかし実際には、講師の担当講座が変わると複数行の更新が必要になり、更新異常が発生します。BCNF はこの例外を認めません。
実務での扱い
実務では 3NF と BCNF はほぼ同義として扱われることが多く、明確に意識する場面は限定的です。代理キー(id BIGSERIAL)を主キーにするスキーマでは候補キーが重なりにくいため、BCNF 違反は自然に起きにくいからです。
BCNF を検討すべき場面: 複数の自然キー候補が重なっているスキーマ、特に多対多・役割割当・予約・時間割のような「組み合わせ」を扱うテーブル。そうでなければ 3NF を目標にすれば十分です。
