本文属于读书笔记,大部分内容摘抄于《高性能MYSQL》,摘抄内容版权属于原作者。
在对比这两者之前,首先我们需要温习一下范式和反范式的定义。
反范式定义:
反范式是通过增加冗余数据或数据分组来提高数据库读性能的过程。
在范式化的数据库中,每个事实数据会出现并且只出现一次,而在反范式化的数据库中,我们会在不同的表中存储同样的数据作为冗余信息。
范式和反范式都有优缺点:
本文属于读书笔记,大部分内容摘抄于《高性能MYSQL》,摘抄内容版权属于原作者。
范式
优点:
- 范式化的更新操作通常比反范式化要快。
- 当数据性能比较好的范式化,就只有很少或者没有重复数据,所以只需要修改更少的数据。
- 范式化的表通常更小,可以更好的放在内存,所以操作起来会更快。
- 很少有多余的数据意味着检索列表数据时更少需要DISTINCT或者GROUP BY语句。
缺点:
范式化的缺点也非常明显,那就是很多数据不能直接从一张表上查到,也就是必须做关联,稍微复杂一些的查询语句可能都要做一次以上的关联甚至更多。这不仅代价昂贵,也可能使得一些索引策略失效。
反范式
优点:
- 正好和范式反过来,因为有大量的冗余数据都在一张表中,可以很好的避免关联。因为不需要关联,那么即使在查询最差的情况下(无索引)全表扫描,当数据比内存大时这可能会比关联快得多,因为避免了随机I/O。
- 单独的表也能使用更好的索引策略。
缺点:
- 理所当然的会有大量冗余数据。
- 更新操作比范式慢。
- 数据同步需要花费。
- 可能需要多的用到DISTINCT和GROUP BY语句。
这是两种理想状况的分析,但是在实际应用中基本不会出现完全的范式化和完全的反范式化这些极端的情况。实际应用中经常需要混用,可能使用部分范式化的schema、缓存表,以及其他技巧。
最常见的反范式化数据的方法是复制或者缓存,在不同的表中存储相同的特定列。在mysql5.0和更新版本中,可以使用触发器更新魂村支,这使得实现这样的方案变得更加简单。
而从附表冗余一些数据到子表也会更高效的执行排序。