数据库的范式化和反范式化
范式与反范式
三大范式
第一范式(1NF):要求数据库表的每一列都是不可分割的原子数据项。
第二范式(2NF):在1NF的基础上,非码属性必须完全依赖于候选码(在1NF基础上消除非主属性对主码的部分函数依赖)
第二范式需要确保数据库表中的每一列都和主键相关,而不能只与主键的某一部分相关(主要针对联合主键而言)。
第三范式(3NF):在2NF基础上,任何非主属性不依赖于其它非主属性(在2NF基础上消除传递依赖)
第三范式需要确保数据表中的每一列数据都和主键直接相关,而不能间接相关。
反范式
接触过关系型数据库的我们肯定都接知道三大范式,但很多人不知道的是还存在反范式,即完全不符合范式定义的数据库结构。
在范式化的数据库中,每个事实数据会出现且只出现一次。而相反,在反范式化的数据库中,信息是冗余的,可能会存储在多个地方。
范式的优缺点
在设计数据库时,通常被建议对数据库架构进行范式化设计,尤其是在写密集的场景。因为范式化有以下优点:
- 范式化的更新操作通常比反范式化要快。
- 当数据较好地范式化时,就只有很少或者没有重复数据,所以只需要修改更少的数据。
- 范式化的表通常更小,可以更好地放在内存里,所以执行操作会更快。
- 很少有多余的数据意味着检索列表数据时更少需要 DISTINCT 或者 GROUP BY 语句。
当然范式化也有缺点:
缺点是范式化设计的架构通常需要关联。稍微复杂一些的查询语句在符合范式的结构上可能至少需要一次关联。这不但代价昂贵,也可能使一些索引策略无效。
例如,范式化可能将列存放在不同的表中,而这些列如果在一个表本可以属于同一个索引。
反范式化的优缺点
优点:
- 反范式化因为所有数据都在一张表中,可以很好地避免关联。(在对大部分查询最差的情况----全表扫描,当数据比内存大时这可能比关联要快得多,因为这样避免了随机I/O)
- 单独的表也能使用更有效的索引策略。
但缺点也是明显的,会有大量的数据冗余,在简单查询时都需要 DISTINCT 或者 GROUP BY 语句。
而且在插入和删除操作上会存在很多问题,要修改的地方会比较多。在数据比较多的时候,占用的内存也会更大。
混合使用范式化和反范式化
实际上,完全的范式化和完全的反范式化的架构都是实验室里才有的东西。在实际应用中经常混合使用,可能使用部分范式化的结构、缓存表,以及其他技巧。
常见的反范式化数据的方法是复制或者缓存,在不同的表中存储相同的特定列。