# 范式和反范式

在范式化的数据库中,每个事实数据会出现并且只出现一次,相反,在反范式化的数据库中,信息是冗余的,可能会存储在多个地方。

# 范式的优点和缺点

当为性能问题而寻求帮助时,经常会被建议对 schema 进行范式化设计,尤其是写秘籍的场景。因为下面这些原因,范式化通常能够带来好处:

  • 范式化的更新操作通常比反范式化要快

  • 当数据较好的范式化时,只有很少或则没有重复数据,所以值需要修改更少的数据。

  • 范式化的表通常更小,可以更好的放在内存里,所以执行操作会更快

  • 很少有多余的数据意味着检索列表数据时更少需要 DISTINCT 或则 GROUP BY 语句。

    比如部门表如果是一张单独的表,则只需要简单的查询这张表就行了。

范式化设计的 schema 的缺点是通常需要关联。稍微复杂一些的查询语句在符合范式化的 schema 上都可能需要至少一次关联,也许更多。这不但代价昂贵,也可能是一些索引测量无效。

例如,范式化可能将列存放在不同的表中,而这些列如果在一个表中本可以属于同一个索引。

# 反范式的有点和缺点

反范式化的 schema 因为所有数据都在一张表中,可以很好的避免关联。

如果 不需要关联表,则对大部分查询最差的情况则:即使没有使用索引,全表扫描。当数据比内存大时这可能比关联要快得多,因为这样避免了随机 I/O。

单独的表也能使用更有效的索引测量。就是将数据冗余在一张表中,并给他们添加索引,这会更快。

# 混用范式化和反范式化

范式化和反范式化的 schema 各有优劣,怎么选择最佳的设计?

最常见的反范式化数据的方法是复制或则缓存,在不同的表中存储相同的特定列。在 MySQL 5.+ 版本中,可以使用触发器更新缓存值。

从父表冗余到一些数据到子表的理由是排序的需要。