数据库设计三大范式

数据库设计三大范式

三月 29, 2017

第一范式

要符合第一范式(1NF),数据库中的每一个表必须具有以下两个性质:

  • 每一列必须仅包含一个值(原子性,不可分割性);
  • 所有表都不能具有相关数据的重复列。

如果表中用一个字段存储人员的完整地址(街道、城市、州、邮政编码、国家),那么这个表就不符合第一范式,因为一列中包含了多个值,违反了上边的第一个特性。

再比如,包含演员1、演员2、演员3等列的电影表也不符合第一范式,因为它违反了第二个特性,这些列包含的信息类型完全相同。

(每个表都要有一个主键是第一范式中的隐含思想)

**提示 **

  1. 理解第一范式最简单的方法是,他就是横向分析表的规则:检查单独一行的所有列,确保唯一性并避免出现类似的数据。
  2. 各种资料会以各种不同的方式来描述范式,很可能使用很多的技术术语。但关键是要理解规范化本质及最终结果,而不是各种规则的技术性措辞。

第二范式

如果数据库要符合第二范式(2NF),数据库首先必须符合第一范式(必须按顺序规范化)。然后,表的每一个不为键(例如,外键)的列必须依赖主键。当某一列在多行中具有相同的非健值时,通常可以确定它违反了这个规则。这些值应该存储在它们自己的表中。并且通过键关联回原来的表。

规范化其实可以理解为创建更多表的过程,直到所有潜在的冗余都被消除为止。

要实现第二范式的最后一步时结合外健来连接关联表。记住,一个表的主键通常是另一个表的外健。

提示

测试第二范式的另外一个方法就是查看表之间的关系。理想的情况是创建一对一或一对多的情况。有多对多关系的表则需要重新组织。

当一个表所有的列都是健的时候,这个表就是一个中介表。

经过恰当规范化的数据库永远不会有重复的行出现在同一个表中。(两个或更多的行的所有非主键列相同)

为了简化规范化的过程,记住第一范式是一个横向检查表的问题,而第二范式是一个纵向的分析(搜索多行上的重复的值)。

第三范式

如果数据库符合第二范式,并且每个非键列互相之间都是独立的,那它就符合第三范式(3NF)。如果你正确按照规范化的过程,就可能没有第三范式的问题。如果改变一列中的值需要改变另外一列的值,那就是违反了第三范式。

网络解释如下:


数据库中的范式有第一范式(1NF),第二范式(2NF),第三范式(3NF),巴斯-科德范式(BCNF),第四范式(4NF),第五范式(5NF)(又称完美范式) 第一范式—-数据库中的表(所有字段值)都是不可分割的原子数据项。 第二范式—-数据库表中的每一列都和主键相关,而不能只和主键的某一部分相关。也就是说 一个表中只能只能包含一个,不能把多种数据保存在同一个表中。 第三范式—-数据库表中每一列数据都和主键直接相关,不能间接相关

为了建立冗余较小、结构合理的数据库,设计数据库时必须遵循一定的规则。在关系型数据库中这种规则就称为范式。范式是符合某一种设计要求的总结。要想设计一个结构合理的关系型数据库,必须满足一定的范式。

1**.第一范式(确保每列保持原子性)**

第一范式是最基本的范式。如果数据库表中的所有字段值都是不可分解的原子值,就说明该数据库表满足了第一范式。

第一范式的合理遵循需要根据系统的实际需求来定。比如某些数据库系统中需要用到“地址”这个属性,本来直接将“地址”属性设计成一个数据库表的字段就行。但是如果系统经常会访问“地址”属性中的“城市”部分,那么就非要将“地址”这个属性重新拆分为省份、城市、详细地址等多个部分进行存储,这样在对地址中某一部分操作的时候将非常方便。这样设计才算满足了数据库的第一范式,如下表所示。

img

上表所示的用户信息遵循了第一范式的要求,这样在对用户使用城市进行分类的时候就非常方便,也提高了数据库的性能。

2**.第二范式(确保表中的每列都和主键相关)**

第二范式在第一范式的基础之上更进一层。第二范式需要确保数据库表中的每一列都和主键相关,而不能只与主键的某一部分相关(主要针对联合主键而言)。也就是说在一个数据库表中,一个表中只能保存一种数据,不可以把多种数据保存在同一张数据库表中。

比如要设计一个订单信息表,因为订单中可能会有多种商品,所以要将订单编号和商品编号作为数据库表的联合主键,如下表所示。

订单信息表img

这样就产生一个问题:这个表中是以订单编号和商品编号作为联合主键。这样在该表中商品名称、单位、商品价格等信息不与该表的主键相关,而仅仅是与商品编号相关。所以在这里违反了第二范式的设计原则。

而如果把这个订单信息表进行拆分,把商品信息分离到另一个表中,把订单项目表也分离到另一个表中,就非常完美了。如下所示。

img

这样设计,在很大程度上减小了数据库的冗余。如果要获取订单的商品信息,使用商品编号到商品信息表中查询即可。

3**.第三范式(确保每列都和主键列直接相关,而不是间接相关)**

第三范式需要确保数据表中的每一列数据都和主键直接相关,而不能间接相关。

比如在设计一个订单数据表的时候,可以将客户编号作为一个外键和订单表建立相应的关系。而不可以在订单表中添加关于客户其它信息(比如姓名、所属公司等)的字段。如下面这两个表所示的设计就是一个满足第三范式的数据库表。

img

这样在查询订单信息的时候,就可以使用客户编号来引用客户信息表中的记录,也不必在订单信息表中多次输入客户信息的内容,减小了数据冗余。