正規化的判準是候選鍵,不是主鍵

多數中文教材把 2NF/3NF/BCNF 寫成「非主鍵欄位不可以……」。主鍵只是你從一堆候選鍵裡挑來用的那一個,挑哪個是實作決定,跟表的結構好壞無關。

最常見的錯誤推論是這句:

❌ 「Primary Key 為單一欄位,則符合 3NF 亦符合 BCNF。」

反例直接打死:排課表 R(學生, 課程, 老師),存在 老師 → 課程(見 BCNF 拿掉 3NF「只檢查非鍵值欄位」的前提)。現在加一欄 id 當單一欄位主鍵:

R(id, 學生, 課程, 老師)
PK = id(單一欄位)
老師 → 課程                    ← 沒有消失

老師 依然不是 superkey,依然違反 BCNF,「張老師教資料庫」依然抄 50 次。加一個代理鍵改變的只有主鍵,沒有改變任何一條相依。

正確的版本要把條件說滿:

只有當這張表只有一個候選鍵、而且該候選鍵是單一欄位時,3NF 才蘊含 BCNF。

這跟 單一主鍵讓 2NF 自動成立,但重複一點都沒少 是同一個陷阱的兩個版本 — 代理鍵讓條文的檢查通過了,底層的重複一點都沒少。看到教材寫「主鍵」,心裡要自動換成「候選鍵」再判斷一次。