数据库设计的三个范式

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

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

第一范式

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

考虑这样一个表:

Contract表

姓名性别电话
第一范式110001
第二范式110002
第三范式110003

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

Contract表(改进后)

姓名性别家庭电话公司电话
第一范式11000120001
第二范式11000220002
第三范式11000320003

第二范式

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

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

OrderIDProductIDUnitPriceDiscountQuantityProductName
101201307.01第一范式
101202459.01第二范式
101203606.01第三范式

因为在一个订单中可以订购多种产品,所以单单一个 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表

OrderIDProductIDDiscountQuantity
1012017.01
1012029.01
1012036.01

Product表

ProductIDUnitPriceProductName
20130第一范式
20245第二范式
20360第三范式

第三范式

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

考虑一个订单表:

OrderDetail表

OrderIDProductIDDiscountQuantity
1012017.01
1012029.01
1012036.01

Product表

ProductIDUnitPriceProductName
20130第一范式
20245第二范式
20360第三范式

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

OrderDetail表

OrderIDDiscountQuantity
1017.01
1019.01
1016.01

Product表

ProductIDUnitPriceProductName
20130第一范式
20245第二范式
20360第三范式

Order_Product表

OrderIDProductID
101201
101202
101203
有用就打赏一下作者吧!