数据库的三大范式

Mr_Czg

发布于 2018.02.08 13:58 阅读 1664 评论 0

数据库三大范式

      为什么要说三大范式:

      说之前举个例子,个人理解:比如你自己练习的时候创个student表,teacher表啥的很简单。不过想想如果让你去设计一个管理系统,那个时候的表的列和表加主键就很多了。就需要数据的关联性能等。就产生了一种设计数据库的范式。

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

实际开发中最为常见的设计范式有三个

第一范式(1NF)(最基本的范式):

      简单理解:就是无重复的列,确保有一个主键

      所谓第一范式(1NF)是指数据库表的每一列都是不可分割的基本数据项,同一列中不能有多个值,即实体中的某个属性不能有多个值或者不能有重复的属性。如果出现重复的属性,就可能需要定义一个新的实体,新的实体由重复的属性构成,新实体与原实体之间为一对多关系。在第一范式(1NF)中表的每一行只包含一个实例的信息。

      举例:

例如某个数据库中的某一个表:

用户ID

用户Name

用户Age

电话

省份

用户地址

1

张三

12

178520

山东

青岛市朝阳区新华路55

2

李四

35

254688

山西

新郑市薛店北街218

3

王五

32

321486

湖南

二七区大学路198

 

用户地址这个属性,本来直接将用户地址属性设计成一个数据库表的字段就行,但是系统经常会需要这么一个请求,只去访问这个用户在哪个城市进行输出,那么就要将这个字段 进行拆分为省份 城市 详细地址等字段。

这样设计就满足了数据库的第一范式(1NF

 

第二范式(2NF

      简单理解:就是非主属性必须完全依赖于主关键字(针对联合主键)

详细解释:

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

      例如:

设计一个商品订单的信息表(里面有订单编号、商品编号等)

 

订单编号

商品编号

商品名称

数量

单位

商品价格

001

1

Java程序设计

2

56

002

2

C++程序设计

1

30

003

3

Mybatis从入门到精通

1

98

 

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

所以你就会想该怎么样才是符合第二范式的呢?

进行对上面的表格拆分一下:

订单编号

商品编号

数量

001

1

2

002

2

1

003

3

1


 

商品编号

商品名称

单位

商品价格

1

Java程序设计

56

2

C++程序设计

30

3

Mybatis从入门到精通

98

 

相信懂数据库主键关系的人知道为什么这样划分;

 

第三范式(3NF

      简单解释:满足第二范式,所有非主要字段是全部必须依赖于主键

      详细解释:不能存在传递依赖。 除了主键外,其他字段必须依赖主键

          对于传递依赖的解释:如果某一属性依赖于其他非主属性,而其他非主属性又依赖于主键,那么这个属性间接依赖于主键,这称为传递依赖。

          满足第三范式必须先满足第二范式,第三范式要求一个数据数据库表中不包含已在其他表中已包含的非关键字信息,数据表如果不存在非关键字属性对任一候选关键字段的传递依赖则符合第三范式。

 

下面设计了一个正确对的第三范式数据库表作参考:

查询订单的时候,就可以使用商品编号来查询商品信息的记录。

 

订单编号

订单名称

负责人

业务员

数量

商品编号

001

Java程序设计

Mr_chen

小李

2

1

002

C++程序设计

Mr_wang

小王

1

2

003

Mybatis从入门到精通

Miss_jiang

小红

1

3

 

商品编号

商品名称

单位

商品价格

1

Java程序设计

56

2

C++程序设计

30

3

Mybatis从入门到精通

98