数据库设计的三个范式

范式(Normal Form),它是英国人 E.F.Codd(关系数据库的老祖宗)在上个世纪70年代提出关系数据库模型后总结出来的,范式是关系数据库理论的基础,也是设计数据库结构过程中所要遵循的规则和指导方法。

目前有迹可寻的共有8种范式,依次是:1NF,2NF,3NF,BCNF,4NF,5NF,DKNF,6NF。通常所用到的只是前三个范式,即:第一范式(1NF),第二范式(2NF),第三范式(3NF)。

第一范式

强调原子性,存储的数据应该不可以再分。

考虑这样一个表:

Contract表

姓名 性别 电话
第一范式 1 10001
第二范式 1 10002
第三范式 1 10003

如果在实际场景中,一个联系人有家庭电话和公司电话,那么这种表结构设计就没有达到 1NF。要符合 1NF 我们只需把列(电话)拆分:

Contract表(改进后)

姓名 性别 家庭电话 公司电话
第一范式 1 10001 20001
第二范式 1 10002 20002
第三范式 1 10003 20003

第二范式

首先是 1NF,强调唯一性,需要实现每一行数据具有唯一可区分的特性,并不能有部分依赖关系。

考虑一个订单明细表(OrderDetail):

OrderID ProductID UnitPrice Discount Quantity ProductName
101 201 30 7.0 1 第一范式
101 202 45 9.0 1 第二范式
101 203 60 6.0 1 第三范式

因为在一个订单中可以订购多种产品,所以单单一个 OrderID 是不足以成为主键的,主键应该是(OrderID,ProductID)。显而易见 Discount,Quantity完全依赖于主键(OderID,ProductID),而 UnitPrice,ProductName 只依赖于 ProductID。所以 OrderDetail 表不符合 2NF。

不符合 2NF 的设计容易产生冗余数据。

可以把【OrderDetail】表拆分为【OrderDetail】(OrderID,ProductID,Discount,Quantity)和【Product】(ProductID,UnitPrice,ProductName)来消除原订单表中UnitPrice,ProductName多次重复的情况。

OrderDetail表

OrderID ProductID Discount Quantity
101 201 7.0 1
101 202 9.0 1
101 203 6.0 1

Product表

ProductID UnitPrice ProductName
201 30 第一范式
202 45 第二范式
203 60 第三范式

第三范式

首先是 2NF,强调独立性,消除传递依赖。

考虑一个订单表:

OrderDetail表

OrderID ProductID Discount Quantity
101 201 7.0 1
101 202 9.0 1
101 203 6.0 1

Product表

ProductID UnitPrice ProductName
201 30 第一范式
202 45 第二范式
203 60 第三范式

第三范式的要求就是一个表只记录一种数据,可以通过拆分【OrderDetail】为【OrderDetail】(OrderID,Discount, Quantity)和【Product】(ProductID,UnitPrice,ProductName)建立两张表,加外间约束Order_Product中间表从而达到 3NF。

OrderDetail表

OrderID Discount Quantity
101 7.0 1
101 9.0 1
101 6.0 1

Product表

ProductID UnitPrice ProductName
201 30 第一范式
202 45 第二范式
203 60 第三范式

Order_Product表

OrderID ProductID
101 201
101 202
101 203
有用就打赏一下作者吧!