关系型数据库中三范式(Normal Form)指的是表设计时遵循的三种规范化理论,旨在减少表数据的冗余及提高数据的完整性。
一、部分依赖、完全依赖、传递依赖
掌握三范式之前,需要首先弄明白描述表属性之间依赖关系的三个名词:部分依赖、完全依赖、传递依赖。
1、部分依赖:当一个非主属性部分依赖于联合主键的一个部分时,我们说它具有部分依赖。这意味着非主属性只依赖于联合主键中的一个属性,而不是整个联合主键。
2、完全依赖:当一个非主属性(即不是主键的属性)完全依赖于主键时,我们说它具有完全依赖。这意味着改变主键的值会导致非主属性的值发生改变。
3、传递依赖:当一个非主属性依赖于另一个非主属性。这种依赖不是直接依赖于主键,而是通过一个或多个中间非主属性的依赖关系。
二、第一范式
1NF:第一范式,表的每一列都具有原子性,不可再细分;
【反例】:订单表【订单id|地址(省市县乡镇街道小区单元房号)】 订单id为主键
【原因】:地址列可以细分
【优化】:将地址拆分为不可再分的更细粒度的多个列
【正例】:订单表【订单id|省|市|县|乡镇|街道|小区|单元号|房号】
三、第二范式
2NF:第二范式,在满足第一范式的基础上,非主键列必须完全依赖联合主键,即不存在部份依赖;
【反例】:订单表【订单id|商品id|商品名称】订单id+商品id为联合主键
【原因】:满足第一范式(列不可再分),不满足第二范式,因为商品名称列不是完全依赖主键列(订单id+商品id),而是部分依赖于商品id
【优化】:拆分为两张表:订单表和商品表,两张表之间通过商品id关联商品名称
【正例】:订单表【订单id|商品id】
商品表【商品id|商品名称】
四、第三范式
3NF:第三范式,在满足第二范式的基础上,非主属性直接依赖于主键,而非通过其他非主属性间接依赖于主键列,即非主键列之间不存在相互依赖,不存在传递依赖。
【反例】:订单表【订单id|商品id|商品名称】订单id为主键
【原因】:满足第一范式(列不可再分) 满足第二范式(非主属性均完全依赖于联合主键列,但此表无联合主键,故肯定满足),但不满足第三范式,因为商品名称依赖于商品id,商品id依赖于主键列订单id,商品名称通过商品id间接依赖于主键列,存在传递依赖
【优化】 1:拆分为两张表:订单表和商品表,两张表之间通过商品id关联商品名称
【正例】:订单表【订单id|商品id】
商品表【商品id|商品名称】
五、总结
遵循三范式有助于设计出结构良好,数据冗余少的关系型数据库。然而,在实际应用中,为了性能或其他考虑,有时会有意违反这些范式。