关系型数据库:设计范式介绍

范式简单说明

  • 1NF:每一列都是不可分割的原子数据项
  • 2NF:消除非主属性对码的部分函数依赖
  • 3NF:消除非主属性对码的传递函数依赖

 

详细解析查看百度百科:数据库范式

如何理解这几个范式的含义?光看字面意思就非常的晦涩!

这几种范式有什么意义呢?可以简单理解为是一种设计标准。

一般我们是如何设计表字段呢? 似乎并没有什么硬性的要求,可以把一个表搞成几个表,反过来也行;

几十个字段放一起也行,拆分在不同的地方也行。但是,这种随心所欲的设计,项目是走不长远的  

 

1NF:每一列都是不可分割的原子数据项

1NF理解起来比较容易,关系型数据库一般都满足这个,是关系型数据库最基本的要求了。

即每一列所代表的数据属性是不可再分的,就像原子一眼,已经是物质构成的最小单位。如下图:

图1

 

商品类型列包涵了2种属性:分类ID与名称;

这在数据库表中是不可能存在的,即取数据的时候“商品类型”这一列不可能即代表名称又代表ID,符合1NF要求的表应该如下:

图2

 

这样设计就比较清晰明了了;1NF比较好理解,一般都不会犯错误这种错误,但也不排除例外的。

比如难道就不能按照一定格式存储吗,比如这样:分类ID|分类名称、或这样:{cls=分类ID,title=名称}

当然可以那样做!你把“分类ID与类型名称”hash取值再取模再平方都可以。但那样就算是破坏了规则了,旁门左道说的就是如此。

好了,我们的表也已经符合1NF了, 是不是这样就万事大吉了呢?我们来试试看;

 

1、查看每一行数据,发现商品名称、分类ID、类型名称等信息重复多次,数据冗余太大了,待改进!

2、新增记录,假设新设置了一个分类,前台维护数据会发生什么情况呢?

根据图2可以得知,表中的码(就是确定唯一一行数据的一个或多个属性(字段))是:商品ID+日期,根据这个码,才可以区分数据表中的每一条记录

也就是说,这个码是非空的!你现在新增一个分类,码的信息都还没有,那就会直接导致插入异常,待改进 

3、修改记录,现在“名称1”的分类改变了,分类1要改成分类2;

发现有多少条“名称1”的记录就得把对应的分类1改成分类2,如果有上万条记录,估计鼠标都得换好几个,待改进

4、删除记录,现在商品“名称1”下架了,得删除与之相关的信息,发现连分类、销售额等信息都被删掉了,待改进

 

问题这么多,这完全是胡乱设计导致的结果,怎么办才能避免这种结果呢,于是有了2NF

 

2NF:消除非主属性对码的部分函数依赖

这句话有几个名称需要解析一下:

1、主属性,可以理解为码的子集;码就是由一个或多个主属性组成的;

2、非主属性,那当然就是主属性之外的所有字段咯。。

3、部分函数依赖,首先函数依赖可以参考数学里的方程式:y = f(x),即自变量x明确的情况下,y是明确可知的。

那这里说的部分函数依赖是什么意思呢,根据图2看下图

图3

参照上图, y = f(x) 可理解为:非主属性 = f(码),即码确定的情况下,那些非主属性肯定能获取到。

这个部分函数依赖,指的是部分非主属性对码的部分主属性产生依赖,有哪些呢?

很明显:右边的非主属性只对商品ID产生依赖,跟日期无关;

既然要求符合2NF,那就要消除这种部分依赖;那我们就只能拆表了,如下:

图4

数据表也改好了,我们再看看会不会还有问题。现在各表的码如下:

表1:码(商品ID+日期),非主属性“销售额”已经完全依赖于码,不存在部分依赖了

表2:码(商品ID),非主属性也是完全依赖于码

1、查看表2,变成基础数据了,每个员工只有一条记录;查看表1,发现名称、分类等信息没有了,冗余少了很多,有改进!

2、新增记录,还是新增新分类,而表2的码是“商品ID”,新增的分类显然不关员工的“商品ID”啥事,还是会插入异常,待改进!

3、修改记录,还是商品1改分类,因为拆表了,所以在表2把商品1对应的分类1改成分类2就行了,只改了一行数据就搞定!有改进!

4、删除记录,删除商品1相关信息,发现分类还是被删掉了,待改进!

看来拆表了还是没有完全解决问题呀,为什么会这样呢,非主属性已经完全依赖于码了呀?于是3NF出场了 

 

3NF:消除非主属性对码的传递函数依赖

非主属性:这个不用多说了,上面已经解析过。 

传递函数依赖:这个可以理解为2个或多个函数依赖组成的,如:A=f(B) , B = f(C),则 A = T(C)

即由C可得到B,由B可得到A,那由C可得到A,中间多了一层。

图4存在哪些传递依赖关系呢,如下:

在商品ID确定的情况下,可得到分类ID,再由分类ID得到分类名称,这就是所谓的传递函数依赖

我们再继续拆表,如下:

图5

好了,现在看看表1、2、3;完全都符合要求,即是原子性,又没有部分函数依赖,也没有传递函数依赖; 

 

1、完全没有数据冗余,数据很简洁

2、新增记录,新增分类,改动的只是分类基础数据表,跟其他表无关。有改进!

3、修改记录,商品1改分类,只改动商品基础数据表,跟其他表无关。有改进!

4、删除记录,删除商品1相关记录, 删除的也是商品基础数据表,和销售表与分类表无关。有改进!

 

posted @ 2017-02-19 20:12  ljr忒修斯之船  阅读(964)  评论(0编辑  收藏  举报