知识卡片

反规范化设计的四种手法及效率与维护成本的权衡

结构图卡

内容

规范化程度越高,查询时往往需要连接的表越多,性能反而可能下降—— 反规范化设计就是在明知违反[[范式体系1NF-BCNF的层层递进标准及各自 消除的冗余类型]]的情况下,主动引入一定冗余来换取查询效率,本质是拿 数据一致性维护成本去交换查询速度,因此必须谨慎权衡,不能作为默认 做法。四种常用手法各自的交易逻辑不同:使用逻辑主码(无实际意义的 整数ID)替代复合主码或复杂类型主码,缩小主码索引占用空间,但代价是 原本由复合主码天然保证的”字段组合非空且不重复”这条约束不会自动 继承,需要额外补一个唯一性索引才能保住这条业务规则,维护成本不减 反增;增加冗余属性(把其他表已有的常用字段复制一份过来)能减少连接 操作次数,但这份复制出来的数据一旦源头修改,必须同步维护多处,只 适合几乎不会被修改的属性;增加导出属性(把可以计算得出的结果预先 存一份)能减少查询时的计算量,代价与冗余属性相同——源数据变了, 导出值也要跟着重算;分割表(水平分割按行拆、垂直分割按列拆)能让 单次查询需要扫描的数据量变小,但只在数据量真正巨大时才划算,数据量 不大时反而会让表结构复杂化、增加SQL编写和维护难度。四种手法没有 一种是”免费的午餐”,选择依据始终是查询效率的实际收益是否明显超过 新增的维护成本。

结构图

flowchart TD
    A[反规范化设计] --> B[逻辑主码替代复合主码<br/>缩小索引空间,但需额外补唯一性约束]
    A --> C[增加冗余属性<br/>减少连接,但需同步维护多处]
    A --> D[增加导出属性<br/>减少计算量,但源数据变化需同步重算]
    A --> E[分割表:水平/垂直<br/>减少单次扫描量,数据量不大时反而复杂化]
    B --> F[效率提升 vs 维护成本增加]
    C --> F
    D --> F
    E --> F

参考来源

- 位置:《数据库原理(微课版)》第7章《关系数据库规范化理论》7.6节 "规范化与反规范化设计"(源文件:_epub-src/index_split_005.html) - 结论依据:原文逐一说明四种方法的效率收益和代价,如"使用逻辑主码 ……原数据库设计时给出的……非空、无重复值的约束是否还需要添加? 若不添加,有可能……若另外再添加……数据维护的工作量反而增加了"" 增加冗余属性、导出属性可提高查询效率,但同时会增加数据维护的 工作量……只有那些几乎不会被修改的属性才可以作为冗余属性添加", 因此可以推出四种手法都是效率与维护成本的权衡而非无代价的优化。 - 原始内容:增加冗余属性、导出属性可提高查询效率,但同时会增加数据 维护的工作量……只有那些几乎不会被修改的属性才可以作为冗余属性 添加到其他表中去。