数据库设计三范式¶
我们在使用数据库的时候,经常会疑惑应该如何来设计表? 😰 其实这个问题前人已经帮我们解决啦!
研发人员在对数据库长期的使用和研究中做出了一些总结, 并对数据库的设计提出了一些规范. 这些规范被称为: 范式(Normal Form)
目前有迹可循的范式总共有8种, 一般我们只需要遵守3范式即可😊
第一范式¶
概念: 强调列的原子性,即列不能再拆分
例如: 我们想设计一张联系人表,表中应该含有:姓名,电话号码,地址等信息
我们按照如下这种方式来设计是否合理呢?
经过仔细的分析,我们发现这张表里面的contact字段设计不太合理. 假设我们想去更新里面的电话号码会很麻烦! 并且它不满足我们刚才介绍的第一范式
第一范式强调列不能再拆分,为了解决这个问题,我们可以这样重新设计联系人表!
现在我们的表是不是更加合理啦!
第二范式¶
在满足1NF的前提下, 表必须拥有主键列, 非主键字段必须完全依赖于主键列 ,而不能只依赖主键的一部分!
我们来看下下面这张表,这张表叫做订单详情表,其中orderid订单编号,productID 商品的编号,UnitPrice单价,Discount折扣,Count购买数量,ProductName商品名称
我们大致一看,这张表似乎设计的没有问题啊! 那么我们如何才能唯一的确定一行记录呢 ?
很显然,在当前案例中,只有(OrderID和ProductID)组合在一起才能唯一确定一行记录, 像这种主键由多列构成的, 我们可以称它为联合主键
下面我们再来看我们的表中数据, 同样一款商品霸王洗发水UnitPrice和ProductName在表中出现了多次,并且这两个信息完全依赖于ProductID,
而Discount和Count则是完全依赖于主键(OrderID,ProductID)
由于UnitPrice和ProductName没有完全依赖于主键(OrderID,ProductID),所以它不满足第二范式
那么我们应该如何让我们上面的表满足第二范式呢? 这里我们要进行拆表操作啦! 将原本一张表中的数据,拆到两张表中!
如下所示:
第三范式¶
满足2NF的前提下, 非主键列必须完全依赖主键列,不能存在非主键列A依赖非主键列B, 非主键列B依赖于主键列的情况,即不能存在传递依赖!
第三范式和第二范式非常容易搞混淆,我们还是以实际案例的方式来演示吧!
首先,我们来看一下下面这张表
当前Order表中
- 主键列: OrderId
- 非主键列: OrderDate订单日期,UserID用户编号,UserName用户名,UserAddr用户地址
在当前表中,出现了一种情况就是UserName依赖于UserID,而UserID又依赖于OrderId,即出现了传递依赖的情况
那么我们如何才能解决上面的问题呢? 大家可能已经想到了,我们可以进行拆表
现在我们的表结构越来越清晰了吧!
三范式总结¶
- 所谓的范式,其实就是我们设计数据库时应该遵守的一种规范
- 第一范式: 强调列应该是最小单元,不能再分
- 第二范式: 强调必须要有主键,并且非主键列必须完全依赖主键列,不能出现部分依赖!
- 第三范式: 强调非主键列必须完全依赖主键列,不能出现传递依赖的情况!
练一练: 请按照三范式设计如下的表,并且描述表与表之间的关系
- 商品表
- 商品分类表
- 商品品牌表
- 订单表
- 用户表
需要注意还需要额外的一些表吗?