目录
1.概述
2.应用举例
3.反范式的新问题
4.反范式的适用场景
有的时候不能简单按照规范要求设计数据表,因为有的数据看似冗余,其实对业务来说十分重要。这个时候,就要遵循业务优先的原则,首先满足业务需求,再尽量减少冗余。
如果数据库中的数据量比较大,系统的UV和PV访问频次比较高,则完全按照MySQL的三大范式设计数据表,读数据时会产生大量的关联查询,在一定程度上会影响数据库的读性能。如果想对查询效率进行优化,反范式优化也是一种优化思路。此时,可以通过在数据表中增加冗余字段来提高数据库的读性能。
规范化 vs 性能
- 为满足某种商业目标 , 数据库性能比规范化数据库更重要
- 在数据规范化的同时 , 要综合考虑数据库的性能
- 通过在给定的表中添加额外的字段,以大量减少需要从中搜索信息所需的时间
- 通过在给定的表中插入计算列,以方便查询
举例1:
员工的信息存储在 employees 表 中,部门信息存储在 departments 表 中。通过 employees 表中的department_id字段与 departments 表建立关联关系。如果要查询一个员工所在部门的名称:
如果经常需要进行这个操作,连接查询就会浪费很多时间。可以在 employees 表中增加一个冗余字段department_name,这样就不用每次都进行连接操作了。
举例2:
反范式化的 设计如下:
举例3:
我们有 2 个表,分别是 和 。商品流水表里有 400 万条流水记录,商品信息表里有 2000 条商品记录。
商品流水表:
商品信息表:
两个表是符合第三范式要求的。但是,在项目的实施过程中,对流水的查询频率很高,而且为了获取商品名称,基本都会用到与商品信息表的连接查询。
为了减少连接,可以直接把商品名称字段加到流水表里面。这样一来,就可以直按从流水表中获取商品名称字段了。虽然增加了冗余字段,但是避免了关联查询,提升了查询的效率。
新的商品流水表如下所示:
反范式可以通过空间换时间,提升查询的效率,但是反范式也会带来一些新问题:
- 存储 了
- 一个表中字段做了修改,另一个表中冗余的字段也需要做同步修改,否则
- 若采用存储过程来支持数据的更新、删除等额外操作,如果更新频繁,会非常
- 在的情况下,反范式不能体现性能的优势,可能还会让数据库的设计更加
当冗余信息有价值或者能 的时候,才会采取反范式的优化
1. 增加冗余字段的建议
增加冗余字段一定要符合如下两个条件。只有满足这两个条件,才可以考虑增加冗余字段。
1)这个冗余字段
2)这个冗余字段查询的时候不可或缺
2. 历史快照、历史数据的需要
在现实生活中,经常需要一些冗余信息,比如订单中的收货人信息,包括姓名、电话和地址等。每次发生的订单收货信息都属于历史快照,需要进行保存,但用户可以随时修改自己的信息,这时保存这些冗余信息是非常有必要的。
反范式优化也常用在数据仓库的设计中,因为数据仓库通常存储历史数据,对增删改的实时性要求不强,对历史数据的分析需求强。这时适当允许数据的冗余度,更方便进行数据分析。
简单总结下数据仓库和数据库在使用上的区别:
1.数据库设计的目的在于捕获数据,而数据仓库设计的目的在于分析数据;
2.数据库对数据的增删改实时性要求强,需要存储在线的用户数据,而数据仓库存储的一般是历史数据;