Normalization vs Denormalization
正则化与反正则化
Terms
在继续之前,先看一些 normalization / denormalization 的常见术语。
Keys
Primary key:用于唯一标识每一行的 column 或 columns 组合。
Composite key:由多个 columns 组成的 primary key。
Super key:能够唯一标识表中所有行的 keys 集合。
Candidate key:可唯一标识行的属性集合。
Foreign key:引用另一个 table 的 primary key。
Alternate key:不是 primary key 的其它候选 keys。
Surrogate key:当没有合适的自然列作为 primary key 时,系统生成的唯一值。
Dependencies
Partial dependency:primary key 只决定了部分属性。
Functional dependency:两个属性之间的依赖关系,通常是 primary key 与 non-key 属性的关系。
Transitive functional dependency:某个 non-key 属性决定了另一个属性。
Anomalies
Database anomaly 常发生在设计不佳、把一切数据都放在 flat table 时。Normalization 用来解决这些问题。
三种常见 anomalies:
Insertion anomaly:没有某些属性时,其他属性无法插入。
Update anomaly:数据冗余导致部分更新不一致,需要额外 update/delete 才能保持一致。
Deletion anomaly:删除某些数据时不得不连带删除其他数据。
Example
下表是一个未 normalized 的 table:
| ID | Name | Role | Team |
|---|---|---|---|
| 1 | Peter | Software Engineer | A |
| 2 | Brian | DevOps Engineer | B |
| 3 | Hailey | Product Manager | C |
| 4 | Hailey | Product Manager | C |
| 5 | Steve | Frontend Engineer | D |
比如我们新招了 John,但他暂时没有 team,这会产生 insertion anomaly。
再比如 Team C 的 Hailey 升职,需要更新两行记录,否则会导致不一致,这就是 update anomaly。
最后,如果我们想删除 Team B,就得同时删除 name 和 role,造成 deletion anomaly。
Normalization
Normalization 是把数据有组织地拆分成表,并建立关系的一种过程,目的是消除冗余、降低依赖冲突、提升一致性。
为什么需要 normalization?
Normalization 的目标是消除 redundant data,确保数据一致性。一个 fully normalized 的 database 更容易扩展新数据类型,不需要大幅修改已有结构,应用层受影响也更小。
Normal forms
Normal forms 是一系列规范,帮助我们判断 database 是否规范化:
1NF
- 不允许重复组
- 相关数据必须用 primary key 标识
- 相关数据应拆成独立 tables
- 同一 column 不能混合数据类型
2NF
- 满足 1NF
- 不能有 partial dependency
3NF
- 满足 2NF
- 不允许 transitive functional dependency
BCNF
Boyce-Codd normal form(BCNF)是 3NF 的更严格版本,也被称为 3.5NF,用于处理 3NF 无法覆盖的问题。
BCNF 的要求:
- 满足 3NF
- 对每个 functional dependency X → Y,X 必须是 super key
还有 4NF、5NF、6NF 等更高范式,这里不展开。可参考这段 amazing video。
在 relational database 中,如果满足 3NF,通常就能避免 insertion、update、deletion anomalies。
现实业务往往无法完全满足规范,如果你决定违反前 3 条范式,请确保应用层能处理可能出现的冗余与依赖问题。
Advantages
- 减少 data redundancy
- 改善 data design
- 提升 data consistency
- 强化 referential integrity
Disadvantages
- 数据设计复杂
- 性能下降
- 维护成本高
- 需要更多 joins
Denormalization
Denormalization 是一种优化手段,通过在一个或多个 tables 中引入冗余数据,减少 costly joins,从而提升 read performance,但会牺牲部分 write performance。数据会被复制到多个 tables 以避免频繁 joins。
当数据通过 federation、sharding 分布到多节点后,跨网络的 joins 更复杂,denormalization 往往可以规避这些问题。
注意:Denormalization 不等于反向执行 normalization。
Advantages
- 读取更快
- 查询更简单
- 表数量减少
- 维护更方便
Disadvantages
- Inserts / updates 成本高
- 数据设计更复杂
- 数据冗余增加
- 一致性风险更高
Trade-off 快览

- Normalization:减少冗余、提升一致性,但 join 成本更高
- Denormalization:读更快,但写入/一致性维护成本更高
示例
- Normalization:客户表 + 订单表分离,避免重复信息
- Denormalization:把热门评论冗余到文章表,换取更快读取