迹忆客 专注技术分享

当前位置:主页 > 学无止境 > 数据库 >

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

作者:迹忆客 最近更新:2021/07/30 浏览次数:

第二范式的前提要求是必须要满足第一范式,在满足第一范式的基础上又增加了两个内容。一是每张表必须要有主键,这一点和在第一范式那一篇的最后将其作为了第一范式的最后一条规则;二是没有包含在主键中的列必须完全依赖于主键,而不能只依赖于主键的一部分。

关于第一范式可以查看上一篇文章数据库设计规范之第一范式(1NF)

这要怎么理解呢,我们还是通过一个例子来试图分析它。

我们有一张 客户-订单 关系表。我们想存储客户的ID,客户姓名、订单 ID 和订单详细信息以及购买日期。结构如下:

CREATE TABLE MEMBERS(
   MEM_ID    INT              NOT NULL,
   MEM_NAME VARCHAR (20)      NOT NULL,
   ORDER_ID   INT              NOT NULL,
   ORDER_DETAIL VARCHAR (20)  NOT NULL,
   SALE_DATE  DATETIME,
   PRIMARY KEY (MEM_ID, ORDER_ID)
);

该表满足第一范式;因为它遵守第一范式的所有规则。PRIMARY KEY (MEM_ID, ORDER_ID)定义了该表的主键由 MEM_ID 和 ORDER_ID 组成。假设同一个客户不会订购相同的东西,那么这二者就可以标识唯一的一条记录。

但是,该表不满足第二范式,因为存在主键和列的部分依赖关系。MEM_NAME 依赖于 MEM_ID,并且客户的姓名和他购买的东西之间没有真正的联系。订单详细信息和购买日期也取决于 ORDER_ID,但它们不取决于 MEM_ID,因为 MEM_ID 与 ORDER_DETAIL和 SALE_DATE 之间也没有必然的联系。

为了使这张表符合第二范式,需要将相关的列分成三个表。

首先,创建一个表来存储客户详细信息。

CREATE TABLE MEMBERS(
   MEM_ID    INT              NOT NULL,
   MEM_NAME VARCHAR (20)      NOT NULL,
   PRIMARY KEY (MEM_ID)
);

然后是创建一个表来存储每个订单的详细信息。

CREATE TABLE ORDERS(
   ORDER_ID   INT              NOT NULL,
   ORDER_DETAIL VARCHAR (20)  NOT NULL,
   PRIMARY KEY (ORDER_ID)
);

最后是将二者的对应关系单独存到一张表里,用各自表的主键作为该表的外键进行关联。然后加上SALE_DATE 来表示该客户下单的时间。如下:

CREATE TABLE MEMBERORDERS(
   MEM_ID    INT              NOT NULL,
   ORDER_ID   INT              NOT NULL,
   SALE_DATE  DATETIME,
   PRIMARY KEY (CUST_ID, ORDER_ID)
);

综上三张表满足了第二范式(2NF)。当然它肯定也是满足第一范式的。

总结

第二范式(2NF)要求实体的属性完全依赖于主关键字。所谓完全依赖是指不能存在仅依赖主关键字一部分的属性,如果存在,那么这个属性和主关键字的这一部分应该分离出来形成一个新的实体,新实体与原实体之间是一对多的关系。为实现区分通常需要为表加上一个列,以存储各个实例的唯一标识。

在接下来的 数据库设计规范之第三范式 的介绍中,我们会看到第三范式和第二范式很像,容易混淆。但是仔细对比例子还是能找出区分的关键点。

除非注明转载,本站文章均为原创或翻译,欢迎转载,转载请以链接形式注明出处

本文地址:

迹忆客

专注技术分享,项目实战分享!

技术宅 乐于分享 7年编程经验
社交账号
  • https://www.github.com/onmpw
  • qq:1244347461

热门文章

教程更新

热门标签