什么是范式?
首先我们要了解什么是范式,可以简单的理解为规范。正式一点的概念是:**范式是符合某一设计要求的总结,要想设计出一个结构合理的关系型数据库,就必须要满足一定的范式。**我们为了建立冗余较小、结构合理的数据库,所以在数据库设计时必须遵循一定的规则,而我们把在关系型数据库中的这种规则称为范式。注意,范式只适用于关系型数据库。
关系型数据库中的三大范式
在实际开发的过程中,我们用的比较多的是三大范式,当然还有反三范式,这里不做讨论。三大范式的概念如下:
第一范式(1NF):每列具有原子性,即不可分割。
第二范式(2NF):每列都和主键相关,可以理解为依赖关系,即每一列都要要依赖于主键。
第三范式(3NF):每列都和主键直接相关,而不能是间接相关,可以理解为只能依赖于主键。
注意:只有先满足1NF,才能满足2NF,只有先满足2NF,才能满足3NF,也就是说越来越严格,2NF比1NF严格,3NF比2NF严格。
三范式的理解
上面说到了三范式的内容,下面谈一下三范式的简单理解。
1、第一范式(1NF)
第一范式是表中的列具有原子性,必须是不可分割的最小单元。举一个简单的例子,我们在设计表时常用到地址这个字段,如下:
如果我们要经常访问地址中的城市,比如黄冈、武汉、渝北这些值,那么以上的表就可能就不能很好的满足要求了,这时可以将地址具体拆分为省份和城市,甚至是详细地址,这样的话在访问数据表的时候性能就非常的高了。如下:
将地址字段重新拆分成省份、城市、详细地址的话,就可以单独的访问地址中的某个值了,这样的设计满足第一范式,这样在访问数据库的时候大大提高了性能。
2、第二范式(2NF)
第二范式在满足第一范式的基础上更进一步,要求表中的每一列都和主键相关,每一列都要依赖于主键。不能存在和主键没有关系的列,也就是说一张表只描述一件事情,只存在一种数据,不能把多种数据存放在同一张表中,举个例子:订单表中只描述订单相关的数据,商品表中只描述商品,不能把商品的相关数据放在订单表中,如下:
上面表的设计就不满足第二范式,这张表中存放了订单数据和商品数据,很明显这样是不合理的,订单表中只能存放订单数据,商品表中只存放商品数据,这样才合理,可以将上表拆分为订单表和商品表,订单表中只放订单相关的数据,商品表中只存放商品相关的数据。订单表如下:
如上订单表中只存放与订单有关的数据,如客户名称、送货地址、电话等信息。
而商品表中只存放商品相关信息:如下:
订单表和商品表必须要关联起来,所以添加一个关联的表,如下:
关联表中只存放订单ID、商品ID、商品数量这3列数据。
查询的时候只需将订单表、商品表、订单商品表这3张表进行关联就行了,SQL如下:
select
distinct
d4.order_id 订单编号,d4.account_name 客户名称,d4.receive_address 收获地址,
d5.s_name 商品名称,d6.s_number 数量,d5.s_price*d6.s_number 商品小计
from d4
inner join d6
on d4.order_id = d6.order_id
inner join d5
on d5.s_id = d6.s_id;
查询结果如下:
3、第三范式(3NF)
第三范式在满足第二范式的基础上更严格一点,确保表中的每列和主键直接相关,而不是间接相关,可以理解为消除依赖之间的传递关系,也就是消除冗余信息,第三范式要求数据库表中不能包含已在其他表中存在的非主关键字信息。比如上面的订单表中,将订单表继续拆分,将顾客信息分离出去,重新建立一张顾客表,只存顾客相关信息,而在订单表中值只保留订单ID和客户ID,如下:
新增的客户表中只保留客户相关信息,客户ID作为主键,包含客户名称、送货地址、联系方式等信息。如下:
查询的时候只需将订单表、客户表、商品表、订单商品表这4张表进行关联即可,SQL如下:
select
distinct
d4.order_id 订单编号,d7.account_name 客户名称,d7.receive_address 收获地址,d7.phone 联系方式,
d5.s_name 商品名称,d6.s_number 数量,d5.s_price*d6.s_number 商品小计
from d4
inner join d6
on d4.order_id = d6.order_id
inner join d5
on d5.s_id = d6.s_id
inner join d7
on d7.id = d4.account_id;
查询结果如下:
总结
可以简单的做一个小结:
第1范式是表中的列不能再次进行分割,即每一列必须是不可分割的最小单元。
第2范式是一张表中包含了不同的属性数据,必须要进行分表,将不同属性的数据存放到不同的表中。
第3范式是已经在第2范式的基础上进行了分表,在一张表中只能包含另一张表中的主键ID,不能包含其他信息。
区分1NF和2NF的关键是是否分表。
区分2NF和3NF的关键是分表后表中是否只包含另一张表中的主键,而不含其他的信息。
一起学习,一起进步,每天只要进步一点点,时间久了,就是质的飞跃。