数据库的范式,主键,外键,候选键

范式

      这里我只说说第一,第二和第三范式,因为目前接触到的项目,感觉满足第三范式就可以了。

      首先是第一范式,第一范式是数据库表必须满足的最低要求,简单的说,就是你的表如果连第一范式都不能满足,那就不是一个数据库的表了。所谓第一范式是指,你的数据库中表的字段都必须是一个不可分割的属性字段。例如下表:

      数据库的范式,主键,外键,候选键数据库的范式,主键,外键,候选键

      这个表中的研究生字段有两个值,它就不满足第一范式,他可以分割成如下表的形式:

      数据库的范式,主键,外键,候选键数据库的范式,主键,外键,候选键

      分割之后的上表就是满足第一范式的表,这个比较简单,相信大家都能理解。

     其次是第二范式,我觉得要理解第二范式首先要理解一个概念,那就是主关键字(主键)

       主关键字是从表的候选关键字中挑选出来的,作为表的行的唯一标识一个字段或多个字段。所谓候选关键字,是指一个属性集,这个属性集能够唯一确定表中的一行,但是去掉任何一个属性之后,就无法唯一确定表中的一行,一般来说,表中只有一个候选关键字,也有可能有多个候选关键字的情况,这个时候就从多个候选关键字中挑选出一个关键字作为主关键字。至于挑选的原则,这个应该没有规定,我觉得一般都是挑选属性少,类型简单的作为主关键字。

       理解了主关键字,再来看第二范式,第二范式是建立在你的表已经满足了第一范式的基础上的。第二范式首先要求你要有主关键字,其次要求你的所有非主关键字的属性都必须是完全依赖于主关键字。所谓完全依赖就是,你的表中的某个非关键字属性不能由主关键字中的一部分属性。如果主关键字中去掉一个或几个属性也能唯一确定某个非关键字属性,那就是不满足第二范式,必须要把这个属性和它依赖的部分单独划分成一个新表。

       然后是第三范式,第三范式也是建立在满足第二范式的基础上的。第三范式要求你的表中不能包含其他表中的非关键字信息。简单来说,第三范式的目的就是防止数据冗余,你在其他表的非关键字信息字段中已经存储的信息,不能在另一个表中再存储一遍。当然,外键不算,外键包含的是其它表的主键。

 

 

 

 

外键

        所谓外键,简单来说就是表A的主键K,与表B中的属性集K相对应,那么这时K就是表B的外建。表A被称为主表,也称为目标关系或被参照关系,表B被称为从表,亦被称为参照关系。其中需要注意的是KF的属性名称可以不同,但是类型必须相同。

       另一个需要注意的问题是,我在百度百科上查到的外键定义是:

F是基本关系R的一个或一组属性,但不是关系的键Ks是基本关系S的主键。如果FKs相对应,则称FR的外键,并称基本关系R参照关系,基本关系S为被参照关系或目标关系。

       从上面定义的红色字体可以看出,这个定义上说的外键不是从表的键,那么我产生了一个问题,那就是从表的外键可不可以也是从表的主键,最后我得出的结论是可以的,所以上面我给的定义中,并没有标明属性集KB的非键属性。至于为什么得出这个结论,是根据实际中的例子得出来的,例如下图(图片亦来自百度百科):

      数据库的范式,主键,外键,候选键数据库的范式,主键,外键,候选键

      上图中,表2的学号既是对应表1的外键,也是表的主键。

       外键的作用

       了解了外键的概念,或许你还是很糊涂,外键到底是干嘛的,为什么要设置外键。

        简而言之,外键的作用就是保持数据库表中的数据的完整性和一致性,主要目的是使两表形成关联,以便于控制从表中的数据。

        为什么要控制呢,例如上图中,如果我在表2中插入了一条新数据,其中学好为20150222222,这个学号在表1中不存在。这显然是不合理的,你学校的数据库没有拥有这个学号的学生,却有这个学好的成绩。还有如果你在表1中删除了一行数据,代表这个学生已经不再我学校中了,但是表2中却还有这个同学的成绩,这显示也是不合理的,这就是数据库中的数据不完整了。

        那么如何控制呢,有两种方式,分别是级联执行和阻止执,其中级联执行,主要是针对主表的操作会在从表中进行相应的操作:

阻止执行

  • 从表插入新行,其外键值不是主表的主键值便阻止插入;
  • 从表修改外键值,新值不是主表的主键值便阻止修改;
  • 主表删除行,其主键值在从表里存在便阻止删除(要想删除,必须先删除从表的相关行);
  • 主表修改主键值,旧值在从表里存在便阻止修改(要想修改,必须先删除从表的相关行)。

级联执行

  • 主表删除行,连带从表的相关行一起删除;
  • 主表修改主键值,连带从表相关行的外键值一起修改。

 

       两种方法提供给用户选择。无论选取哪种方法,从表里都不会有多余行。从另一个角度理解,用拒绝同一事物在从表中的标志与主表不一致来实现与主表中的标志一致。

       设置级联,是在从表设置外键的时候进行的,设置的语法CASCADE为级联执行、RESTRICT为阻止执行。例如:

级联执行:foreign key(id) references outTable(id) on deletecascade on update cascade);