范式化 — 消除更新异常的规则
一句话总结
规范化让同一事实只存一处,目的不是节省空间,而是消除更新、插入和删除异常。
范式
1NF 要求原子值;2NF 消除对复合键部分的依赖;3NF 消除对非键列的依赖。核心原则是一个事实只写一次。
函数依赖表示一项确定后另一项也唯一确定。以下例子展示了判断过程:
주문상세(주문번호, 상품번호, 수량, 상품명, 단가, 고객번호, 고객명, 고객주소)
키: (주문번호, 상품번호)
화살표를 그려 보면:
(주문번호, 상품번호) → 수량 ← 키 전체에 종속. 정상
상품번호 → 상품명, 단가 ← 키의 "일부" 에만 종속. 2정규형 위반
주문번호 → 고객번호 ← 키의 "일부" 에만 종속. 2정규형 위반
고객번호 → 고객명, 고객주소 ← 키가 아닌 것에 종속. 3정규형 위반
按箭头拆分,左侧成为新表的键:
주문상세(주문번호, 상품번호, 수량)
상품(상품번호, 상품명, 단가)
주문(주문번호, 고객번호, 주문일)
고객(고객번호, 고객명, 고객주소)
例如复合键 (주문번호, 상품번호) 中,상품명 只依赖商品编号;우편번호 与 도시 也可能形成依赖。符号 A → B 表示 A 确定后 B 唯一确定。
领域知识决定依赖是否真实成立。BCNF 处理候选键交叠的少见情况,实务通常做到 3NF。
性能与反规范化
规范化虽然增加连接,但行和索引更小,更新也更快。常见性能问题其实是外键缺少索引;PostgreSQL 会自动索引主键,却不会自动索引外键。
物化评论数等聚合值可以合理反规范化,但必须记录为什么这样做、如何保证一致性,以及用于修复的重算查询。热门数据还可能形成锁竞争;多数计数器晚五秒并无影响。
判断标准
应理解每个范式消除的异常,并明确何时值得承担反规范化成本。