数据库范式

刚看了一遍博客园原文讲三大范式(关系型数据库),是我觉看到目前最通俗的版本
参考于余晟:从范式谈起.

第一范式:属性不能拆分

换句话说,表中间的任何列都应当是承载信息的最小单位,不容许有更小的单位。一个人有身高、体重、性别等等,那么身高、体重、性别都应该对应专门的列,而不能取个名为“基本信息”的列,把这些信息统统塞进去。即数据库表的每一列都是不可分割的原子数据项。这个应该比较好理解,方便数据的索引与去重。

第二范式:主键必须最小

主键是这样的属性:对某个关系中所有n元组来说,主键必须是没有重复的,所以依靠它可以唯一定位某个n元组。主键可以是一个属性,也可以是多个属性。如果用列和表的说法,就是“唯一定位表中某行所要用到的列”。

  假设有一个电商卖家对接到电商平台,用表来存储订单信息,如果所有订单都来自同一个平台,可以用“平台订单号”作为主键;如果来自不同平台,各平台的订单号可能会重复,所以可以用“平台+订单号”作为主键……以此类推。

  第 2 范式的要求是:在满足第 1 范式的基础上,所有非主属性(主键之外的属性)必须完全依赖主键,而不能只依赖主键的某个子集

alt text
上面的表不符合第二范式,主键是“平台+订单号”,这样才能区分金额,但是“对接人邮箱”只与“平台”有关,而“平台”是“平台+订单号”的子集。
  我们经常看到数据库的表会有一个毫无业务意义的自增字段作为主键,这样就保证了第二范式,因为主键只有一个属性,不存在真子集。同时,应当把非主属性和原来它依赖的“主键的子集”单独拿出来建表,比如建立一张“平台+对接人邮箱”的表格。

该范式是规定以最小的主键索引到某行数据

第三范式:主键必须直接依赖

 要满足第 2 范式,首先必须满足第 1 范式。同样的道理,要满足第 3 范式,首先也必须满足第 2 范式,并符合以下要求:所有非主属性对主键的依赖应当是直接的,不容许是间接的。也就是说,所有非主属性不容许依赖主键之外的属性

alt text

上面的表不符合第三范式。主键是“平台+冠军种类”,但属性“品牌联系人邮箱”依赖于主键之外的属性“品牌”,虽然“品牌”依赖于表的主键,但“品牌联系人邮箱”对主键依赖是传递的。

  要让表符合第 3 范式,可以解除传递依赖,把对应的属性拆分出来单独创建表,比如把“品牌”和“品牌联系人邮箱”单独创建表。
alt text

Summary

三大范式核心观点就是去除冗余数据