数据库的三大范式(原理 + 例子详解)

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第15天,点击查看活动详情 >>

数据库的三大范式

为了后面能否详细讲述三大范式并举例,所以在这里先放出一个实例表格(后面根据范式的要求对其进行拆分、修改) image.png

第一范式(确保每一列都保持原子性)

原子性,顾名思义,就是要求每一列都是原子,不可再分;什么叫列可再分,或者不可再分呢?

举个例子,上图中“价格”所在列就包含了两种属性:单价和折后价;这就违背了原子性了,因为这个列明明是可以在分的(分为单价列、折后价列)

image.png

像上图这样拆分之后(单价和折后价单独成列),该表就符合数据库的第一范式了。

第二范式(保证每一列都是和主键有关的)

第二范式是在第一范式的基础上提出的,所以满足第二范式就一定满足第一范式,也就是说要想符合第二范式必须先满足第一范式。

(第一范式是第二范式的必要条件,反过来第二范式是第一范式的充分条件)

看下图:

image.png

因为表中单靠订单号是不符合主键唯一性了,所以要采用联合主键的方式确定每一条记录;假如联合主键为(订单号,产品编码)

上表虽然符合了第一范式,但却不符合第二范式!

因为像产品名称和单价这些并不依赖订单号(联合主键的一部分),需要拆分为不同的表,以确保表中的列都是依赖主键的(如果是联合主键的话,就需要依赖联合主键的所有)

进行以下拆分:

image.png

经过拆分为多个表格,以保证每个表格中的每一列都依赖主键。

第三范式(确保每个列都是直接依赖主键,而不存在间接依赖)

请看下面这个表格:

image.png

上表中,订单号 -> 用户名称 -> 用户ID,因此如果要修改其中某一项信息的时候就会牵涉较广了(耦合),即用户信息不能单独管理了。

再次拆分处理:

image.png

总结

这一次主要介绍了数据库中常见的三种范式,从一到三要求主键提高,第 i - 1范式是第 i 范式的必要条件。

当然啦,在日常实际开发当中,可能并不会完全遵守三大范式,只能说是具体情况具体分析,假如当前情况在表存在冗余的时候,更方便,那就允许存在一定的冗余。

猜你喜欢

转载自juejin.im/post/7130266982556893197