数据库设计第二范式 (2NF)

定义

2NF有以下几条要求:

  1. 建立在1NF之上
  2. 不含有部分依赖(Partial Dependency)

示例1

要求1好理解,但是在要求2中的部分依赖是什么意思?让我们通过一个示例来理解。以下面我们建议了一个用户订单表。

CREATE TABLE Custom_Order(
   ID           INT             NOT NULL,
   Custom_ID    INT             NOT NULL,
   Custom_Name  VARCHAR (20)    NOT NULL,
   Order_ID     INT             NOT NULL,
   Sale_Date    DATETIME        NOT NULL,
   Order_Detail DOUBLE          NOT NULL,
   PRIMARY KEY (ID)
);

该表满足1NF,但不满足2NF,因为主键和列存在部分依赖关系:

  • Custom_Name依赖于Custom_ID。这里的依赖是指即每个用户的编号是唯一的,而名称绑定于这个唯一的ID。即,一个编号只对应一个用户名,而一个用户名可能有多个编号(用户名可以相同)。
  • 客户名与其所购买的商品之间没有直接联系。

所以,Custom_Name 是有依赖的。 同时,订单这个主体也应该独立开,即 Sale_Date 和 Detail 都是有依赖的。若要使此表符合2NF,我们需要将表分成三个表。一个用户表(Customs表),定义用户的相关信息;一个订单表(Orders),表示订单详细信息;一个用户订单表(CustomOrders表)记录用户交易的相关信息。三个表如下所示。

-- 用户信息表
CREATE TABLE Customs(
   ID    INT              NOT NULL,
   NAME VARCHAR (20)      NOT NULL,
   PRIMARY KEY (ID)
);

-- 订单表
CREATE TABLE Orders(
   ID     INT           NOT NULL,
   Detail DOUBLE        NOT NULL,
   PRIMARY KEY (ID)
);

-- 用户订单表
CREATE TABLE CUSTMERORDERS(
   Custom_ID    INT              NOT NULL,
   Order_ID     INT              NOT NULL,
   Sale_Date    DATETIME,
   PRIMARY KEY (CUST_ID, ORDER_ID)
);

通过这个示例我们可以看到,所谓的部分依赖指的是某个(或多个)列依赖于别的列,且和和其他的列没有任何直接关系。当表的设计中有部分依赖时,我们需要将一张表拆分成多张表,这些表包括基本信息表(如Customs表和Orders表)和关系表(如CustomOrders表),从而消除数据的部分依赖。这和设计模式中常说的耦合是一个原则,要尽可能实现低耦合高内聚(low in coupling and high in cohesion)。

示例2

再举行一例,我们从数据冗余角度来看2NF。

编号姓名性别领导姓名领导性别
1001张三
1002李小四张三

如上表所示,我们在个人信息表中包括了其领导的相关信息。领导的信息都使用了实际的值,而不是引用。这样就违反了2NF,在实际应用中就会带来麻烦。比如,李小四的领导换人了,那么需要同时更新“领导姓名”和“领导性别”两列,如果有多个属性,那么就进行相应的更新。在实际应用中,如果很容易出错,导致数据不同步。

所以,根据2NF的原则,我们修改表的结构如下所示。

编号姓名性别领导编号
1001张三0
1002李小四1001

通过对编号的引用,避免了数据不同步的问题,这样无论某人的信息如何修改,编号都不需要改变,在实际显示的时候只需要根据SQL进行联接即可。

总结

2NF要求数据表中对列的引用不能有部分依赖,可以理解为在对不同表的数据引用时,要引用其编号而不是实际的数据。这样带来的设计好处是,数据冗余小(只有编号)且易于修改(修改了被引用表的数据对原表没有影响)。

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值