基本概念:
关系数据库 : 就是用二维表来保存数据
实体: 现实世界中客观存在并可以被区别的事物。比如“一个学生”、“一本书”、“一门课”等等。值得强调的是这里所说的“事物”不仅仅是看得见摸得着的“东西”,它也可以是虚拟的,不如说“老师与学校的关系”。
属性: 教科书上解释为:“实体所具有的某一特性”,由此可见,属性一开始是个逻辑概念,比如说,“性别”是“人”的一个属性。在关系数据库中,属性又是个物理概念,属性可以看作是“表的一列”。
元组 :表中的一行就是一个元组。
分量: 元组的某个属性值。在一个关系数据库中,它是一个操作原子,即关系数据库在做任何操作的时候,属性是“不可分的”。否则就不是关系数据库了。
码: 表中可以唯一确定一个元组的某个属性(或者 属性组 ),如果这样的码有不止一个,那么大家都叫 候选码, 我们从候选码中挑一个出来做老大,它就叫 主码。
全码: 如果一个码包含了所有的属性,这个码就是全码。
主属性: 一个属性只要在任何一个候选码中出现过,这个属性就是主属性。
非主属性: 与上面相反,没有在任何候选码中出现过,这个属性就是非主属性。
外码: 一个属性(或属性组),它不是码,但是它别的表的码,它就是外码。
范式:
第一范式( 1NF ):属性不可分。
在前面我们已经介绍了 属性值 的概念,我们说,它是“不可分的”。而第一范式要求属性也不可分。那么它和属性值不可分有什么区别呢?给一个例子:
name | tel | age | |
大宝 | 13612345678 | 22 | |
小明 | 13988776655 | 010 - 1234567 | 21 |
|
|
|
|
Ps :这个表中,属性值“分”了。
name | tel | age | |
手机 | 座机 | ||
大宝 | 13612345678 | 021 - 9876543 | 22 |
小明 | 13988776655 | 010 - 1234567 | 21 |
Ps :这个表中,属性 “分”了。
这两种情况都不满足第一范式。不满足第一范式的数据库,不是关系数据库!所以,我们在任何关系数据库管理系统中,做不出这样的“表”来。
第二范式( 2NF ) :符合 1NF ,并且, 非主属性完全依赖于码 (即解决非主属性部分依赖码的问题) 。
部分函数依赖 :
在关系模式R(U)中,对于属性 组 X、Y,如果有X→Y,并且对于X的任何一个真子集X ’ 都 不能 得出X ’ →Y,则称Y对X完全函数依赖。而如果X→Y,但Y 不 完全函数依赖于X,则称Y对X部分函数依赖。可见部分函数依赖是在完全函数依赖的基础上定义的,也就是说不满足完全函数依赖就是部分函数依赖。
听起来好像很神秘,其实真的没什么。
一 个候选码中的主属性也可能是好几个。如果一个主属性,它不能单独做为一个候选码,那么它也不能确定任何一个非主属性。给一个反例:我们考虑一个小学的教务 管理系统,学生上课指定一个老师,一本教材,一个教室,一个时间,大家都上课去吧,没有问题。那么数据库怎么设计?(学生上课表)
学生 | 课程 | 老师 | 老师职称 | 教材 | 教室 | 上课时间 |
小明 | 一年级语文(上) | 大宝 | 副教授 | 《小学语文 1 》 | 101 | 14 : 30 |
一个学生上一门课,一定在特定某个教室。所以有(学生,课程)- > 教室
一个学生上一门课,一定是特定某个老师教。所以有(学生,课程)- > 老师
一个学生上一门课,他老师的职称可以确定。所以有(学生,课程)- > 老师职称
一个学生上一门课,一定是特定某个教材。所以有(学生,课程)- > 教材
一个学生上一门课,一定在特定时间。所以有(学生,课程)- > 上课时间
因此(学生,课程)是一个码。
然而,一个课程,一定指定了某个教材,一年级语文肯定用的是《小学语文 1 》,那么就有课程- > 教材。(学生,课程)是个码,课程却决定了教材,这就叫做不完全依赖,或者说部分依赖。出现这样的情况,就不满足第二范式!
有什么不好吗?你可以想想:
1、 校长要新增加一门课程叫“微积分”,教材是《大学数学》,怎么办?学生还没选课,而学生又是主属性,主属性不能空,课程怎么记录呢,教材记到哪呢 ? ……郁闷了吧 ? ( 插入异常 )
2、 下学期没学生学一年级语文(上)了,学一年级语文(下)去了,那么表中将不存在一年级语文(上),也就没了《小学语文 1 》。这时候,校长问:一年级语文(上)用的什么教材啊?……郁闷了吧 ? ( 删除异常 )
3、 校长说:一年级语文(上)换教材,换成《大学语文》。有 10000 个学生选了这么课,改动好大啊!改累死了……郁闷了吧? (修改异常)
那应该怎么解决呢?投影分解,将一个表分解成两个或若干个表
学生 | 课程 | 老师 | 老师职称 | 教室 | 上课时间 |
小明 | 一年级语文(上) | 大宝 | 副教授 | 101 | 14 : 30 |
学生上课表新
课程的表
第三范式( 3NF ): 符合 2NF ,并且, 消除传递依赖 (解决 主 非 属性 传递 依赖于主属性 问题)
传递依赖:
设有关系模式R(U),X、Y、Z是属性 或属性组 ,如果有X→Y,Y→Z,而且 Y→X不成立 、Z不是Y的子集、Z不是X的子集。注意,而且后面的三个条件必须都成立,才能称之为传递依赖。
很多人可能误认为R中存在传递依赖 如,由 A→B、B→C尽管可以 得出 A→C,但是C并不传递依赖A,因为由C→D、D→A可知C→A,不满足传递依赖定义中的条件“Y→X不成立”。但是,A→C是成立的,因为它可根据Armstrong推理系统中的 传递律 (注意,不是传递依赖,不要把两者搞混了),只是不符合传递依赖的定义罢了。
上面的“学生上课表新”符合 2NF ,可以这样验证:两个主属性单独使用,不用确定其它四个非主属性的任何一个。但是它有传递依赖!
在哪呢?问题就出在“老师”和“老师职称”这里。一个老师一定能确定一个老师职称。
有什么问题吗?想想:
1、 老师升级了,变教授了,要改数据库,表中有 N 条,改了 N 次…… (修改异常)
2、 没人选这个老师的课了,老师的职称也没了记录…… (删除异常)
3、 新来一个老师,还没分配教什么课,他的职称记到哪?…… (插入异常)
那应该怎么解决呢?和上面一样,投影分解:
课程 | 教材 |
一年级语文(上) | 《小学语文 1 》 |
学生 | 课程 | 老师 | 教室 | 上课时间 |
小明 | 一年级语文(上) | 大宝 | 101 | 14 : 30 |
BC 范式( BCNF ): 符合 3NF ,并且, 主属性不依赖于 非 主属性
若关系模式属于第一范式,且每个属性都不传递依赖于键码,则R属于BC范式。
通常BC 范式的条件有多种等价的表述:每个非平凡依赖的左边必须包含键码;每个决定因素必须包含键码。
BC 范式既检查非主属性,又检查主属性。当只检查非主属性时,就成了第三范式。满足 BC 范式的关系都必然满足第三范式。
还可以这么说: 若一个关系达到了第三范式,并且它只有一个候选码,或者它的每个候选码都是单属性,则该关系自然达到 BC 范式。
一般,一个数据库设计符合 3NF 或 BCNF 就可以了。在 BC 范式以上还有第四范式、第五范式。
第四范式: 要求把同一表内的多对多关系删除。
第五范式: 从最终结构重新建立原始结构。
但在绝大多数应用中不需要设计到这种程度。并且,某些情况下,过于范式化甚至会对数据库的逻辑可读性和使用效率起到阻碍。数据库中一定程度的冗余并不一定是坏事情。如果你对第四范式、第五范式感兴趣可以看一看专业教材,从头学起,并且忘记我说的一切,以免对你产生误导。