数据库设计三范式

我们在使用数据库的时候,经常会疑惑应该如何来设计表? 😰 其实这个问题前人已经帮我们解决啦!

研发人员在对数据库长期的使用和研究中做出了一些总结, 并对数据库的设计提出了一些规范. 这些规范被称为: 范式(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表中

  1. 主键列: OrderId
  2. 非主键列: OrderDate订单日期,UserID用户编号,UserName用户名,UserAddr用户地址

在当前表中,出现了一种情况就是UserName依赖于UserID,而UserID又依赖于OrderId,即出现了传递依赖的情况

那么我们如何才能解决上面的问题呢? 大家可能已经想到了,我们可以进行拆表

现在我们的表结构越来越清晰了吧!

三范式总结

  1. 所谓的范式,其实就是我们设计数据库时应该遵守的一种规范
  2. 第一范式: 强调列应该是最小单元,不能再分
  3. 第二范式: 强调必须要有主键,并且非主键列必须完全依赖主键列,不能出现部分依赖!
  4. 第三范式: 强调非主键列必须完全依赖主键列,不能出现传递依赖的情况!

练一练: 请按照三范式设计如下的表,并且描述表与表之间的关系

  1. 商品表
  2. 商品分类表
  3. 商品品牌表
  4. 订单表
  5. 用户表

需要注意还需要额外的一些表吗?