bitsCN.com
RDBMS之父Codd于1970年代初提出范式,其出发点是为了减少数据库中数据冗余,增进数据的一致性。但冗余是奢侈的,因为那个年代的存储空间极其昂贵。理解完这一背景并对范式的持续深入后,目的是为了能更好地利用及打破规范和标准。毕竟范式带来了一些问题:
● 紧耦合,表之间表现为强依赖,在业务高速增长后,将导致拆分的老大难问题
深谙范式招数之后,必然是发现招数的局限性,要么忘掉招数,要么自创招数,这就有了反范式
如果说优化器为大脑,存储引擎为手脚,MySQL的大脑目前弱了点,当遇到一些子查询或较为复杂的Join时,很容易头脑短路,表现为错误的驱动表、槽糕的执行计划...等。范式化设计的Schema的缺点如上所述,是通常需要Join成本,而反范式化的Schema因为所有数据都在一张表中,可以很好地避免Join。那么,要减少Join最直接有效的方式就是通过表字段的冗余来实现。而冗余具体该如何实现呢?下面给出几种实现方式:
① 基于静态数据的冗余
基于谓词的冗余
基于聚会函数的冗余
基于排序的冗余
但是增加冗余,必然会牺牲部分数据的一致性。我们有必要对数据一致性问题区分优先级。对用户伤害不大,用户并不是太关心的数据,这是可容忍的。而那些致命又敏感的数据,我们需要在应用层处理,比如作二次校验,定期抽样检查,至于这会不会是个问题,需要权衡写查询的频率与读查询频率。
反范式设计的第二个优势是,因为相关列都位于同一张表里,这也能更有效地制定健壮的索引策略,也就是,在反范式中,更强调索引,而弱化外键。假设有个影视娱乐网站,现想查看最近发布的10部美国大片,范式化后查询也许是这样的:
mysql > SELECT title,actor_name -> FROM film -> INNER JOIN actor ON film.actor_id=actor.id -> WHERE actor.area='AMERICA' -> ORDER BY film.published DESC LIMIT 10;
登录后复制
mysql > SELECT title,actor_name -> FROM actor_film -> WHERE area='AMERICA' -> ORDER BY film.published DESC LIMIT 10;
登录后复制
By 迦叶
2014-1-14
Good Luck!
bitsCN.com