第二范式:
所谓第一范式,是指每个属性的值域的每一个值都是不可分割的。不做解释。
所谓第二范式,是指关系模式R中的每一个非主属性完全依赖于R的某个候选键。
显然,要理解这句话,必须要理解候选键。而这又会扯出主键,超键,外键等相关概念。
超键是一个属性集,可以用来表示唯一元组。也就是说,任意两条记录不存在这个属性集中的所有属性对应的值,完全相等的情况。显然,最普通的情况,一个元组中的所有属性自然构成一个超键。超键当然会有很多种。
候选键首先是一个超键。但是特别的是,他不能拥有任何多余的属性。也就是说,一个超键中去掉任何一个属性都不再是超键,则称之为候选键。
(学号 姓名 性别 年龄 系别 专业 )关系中,{学号 姓名}不是一个超键。因为姓名可以去掉。
主键是一个候选键。特别的是,他是你(用户,设计者)指定的。
个别书中的称呼为超码,候选码,主码,是一回事。
另外,还要理解主属性的概念。官方的课本写的是,如果属性A是关系R中的候选键的一个属性,则A为R的主属性。否则为非主属性。如果属性A是关系R中的任意存在的一个候选键的一个属性,则A为R的主属性。否则为非主属性。(即存在一个候选键包含它即为主属性)
最后,还有倒霉的“完全依赖”四个字需要解释。
请看百度百科的例子
我们假设它符合第一范式,且{货物类型,货物ID}是唯一存在的候选键,
但是,注意事项只依赖域货物类型,和货物ID没关系。这不叫做完全依赖。
换句话说,如果有一个非主属性,不完全依赖于任何一个候选键,就不算第二范式。
最后以上面的例子谈谈第二范式的存在必要性。
一个不好的数据库会存在数据冗余,更新异常,插入异常,和删除异常四个问题。所以我们才会想到规范化的解决方案。
。
把第一范式升级为第二范式,可以减轻插入异常,删除异常,冗余度大,更新异常的。
比如上面的例子,显然拆分成两个符合2NF的表可以减少数据量。这就叫做减少冗余。
所谓更新异常,如果更新了货物类型对应的注意事项,显然只修改一条记录是不可能的。
所谓插入异常,比如说要加入一种新的货物类型,但是如果还没有任何一种具体的货物,就没办法加入
所谓删除异常,比如说删除了某种货物类型的最后一个货物。货物类型和注意事项的关联也被删除了。
第三范式:
每个非主属性都是不传递依赖于R的候选键。
显然,这里需要解释的概念是传递依赖
比如下面的关系(学号,姓名,所在系,系名称,系地址)
取{学号}为主键。单关键字不可能有部分依赖的关系,但是毫无疑问所有字段都依赖于主键。不过,显然,我们上面提到的四种问题都会在这里重演。
BCNF:
BCNF和第三范式类似。说的是每个属性都不传递依赖于R的候选键。但是只要求R在第一范式符合上述例子就可以了.但是可以证明,BCNF一定是3NF,如果在3NF上定义,就是要求数据表中不存在任何字段对任一候选关键字段的传递依赖。
比如说一个仓库,可以选择两种候选键。
(仓库ID, 存储物品ID) →(管理员ID, 数量)
(管理员ID, 存储物品ID) → (仓库ID, 数量)
在这个例子中,假设仓库ID和管理员ID一一对应。显然,这符合第三范式,因为只有一个非主属性数量。且都完全依赖于两个候选键。但是,显然不符合BCNF