数据库设计规范之第三范式(3NF)

在之前的两篇文章数据库设计" title="数据库设计">数据库设计规范" title="数据库设计规范">数据库设计规范之第一范式(1NF) 和数据库设计规范之第二范式(2NF)中我们介绍了第一范式和第二范式。本篇我们来看一下第三范式。

通过第二范式的介绍我们知道第一范式是基础。也就是说无论是第二范式还是接下来要讲的第三范式,前提是都必须要满足第一范式。

而如果要满足第三范式除了要满足第一范式(1NF)之外,还要满足第二范式。如果不符合第二范式,自然也谈不上满足第三范式。所以要满足第三范式,需要满足以下两个条件

  • 满足第二范式

  • 所有非主字段都依赖于主键。

这看起来其实和第二范式没有什么区别。但是这里要注意的是,我们这里的非主字段的依赖说的是数据之间的。举个例子:我们看下面这张表,其中的 街道名称(STREET)、城市(CITY)和省份(PROVINCE)与其邮政编码的对应是固定不变的。像这种邮政编码和地址之间的依赖被称为传递依赖。

CREATETABLE MEMBERS(

MEM_ID INTNOTNULL,

MEM_NAME VARCHAR (20) NOTNULL,

DOB DATE,

STREET VARCHAR(200),

CITY VARCHAR(100),

PROVINCE VARCHAR(100),

ZIP VARCHAR(12),

EMAIL_ID VARCHAR(256),

PRIMARY KEY (MEM_ID)

);

也就是说,现实中这一个城市中会有很多的客户,这样每个客户的记录中都会存储 街道名称(STREET)、城市(CITY)、省份(PROVINCE)和邮政编码这些固定的值。这会造成很多的冗余数据。这是不符合第三范式的。为了符合第三范式,我们需要做的就是将 STREET、CITY 、 PROVINCE 和 ZIP(邮政编码) 字段单独放到一张表中去,然后将 ZIP 作为主键。

CREATETABLE ADDRESS(

ZIP VARCHAR(12),

STREET VARCHAR(200),

CITY VARCHAR(100),

STATE VARCHAR(100),

PRIMARY KEY (ZIP)

);

接下来我们开始改造 MEMBERS 表

CREATETABLE MEMBERS(

MEM_ID INTNOTNULL,

MEM_NAME VARCHAR (20) NOTNULL,

DOB DATE,

ZIP VARCHAR(12),

EMAIL_ID VARCHAR(256),

PRIMARY KEY (MEM_ID)

);

而此时,这张表中的 ZIP 是一个外键,引用的是表 ADDRESS中的主键ZIP。

这样最终的表就可以说是满足了第三范式了。

第二范式和第三范式的概念比较容易混淆,不过通过对比二者的例子,我们还是能找到一些区分的关键点。

对于第二范式(2NF)要检查非主键列是否完全依赖于整个主键,还是说只是依赖于主键的部分列。只要是不完全依赖于整个主键那就不符合第二范式,反之就是符合第二范式。

第三范式(3NF)是要看非主键列除开对主键的依赖,非主键之间是否有固定的依赖关系。并且这种固定的依赖关系和主键之间是不是一种多对一的关系。就像在上面例子中介绍的,地址和邮编之间的关系是固定不变的一对一的。并且主键和具有这种依赖关系的列之间是一种多对一的关系。有这种依赖关系的列就需要单独拿出来做成单独的表。一个地址中可以有多个不同的客户,客户和地址之间是一种多对一的关系。不可能出现两个不同的客户他们所在的地址一样但是邮编不一样的这种情况。因此如果出现这种情况的话,没有把具有传递依赖的列单独做成一张表就不符合第三范式,反之就是符合第三范式。

这里我们仅仅是介绍这几个范式的定义,实际项目中还要根据性能、空间等因素综合考虑来设计表。不可能就是非常严格的必须设计成符合这三种范式的表。

本文转载自:迹忆客(https://www.jiyik.com)

以上是 数据库设计规范之第三范式(3NF) 的全部内容, 来源链接: utcz.com/z/290211.html

回到顶部