关系数据库的基本概念
1、属性和域
属性是什么?其实也就和玩游戏一样!是描述一个事物的若干特征;
那域又是什么???其实域也就是每个属性的取值范围对应的一个值的集合,称为该属性的域(Domain);
2、笛卡儿积与关系
笛卡尔积原理解释:笛卡尔积描述的是多表连接组成一个新表的情况;
说不如做,那就来两颗栗子呗!
【栗子】假设集合A={a, b},集合B={ 0,1, 2 },则两个集合的笛卡尔积为{ (a, 0),(a, 1),(a, 2),(b, 0),(b, 1),(b, 2) };
【栗子】(员工信息表 + 上级信息表)
员工信息表:
上级信息表:
备注:员工信息表中的外键【上级编号】,其实也就是上级信息表中的主键【上级编号】;
笛卡尔积:(结果:8 * 3 = 24 行)
3、关系的相关名词
候选码:若关系中的某一属性组的值能唯一的标识一个元组,则称该属性组为候选码
在最简单的情况下,候选码只包含一个属性
姓名 | 性别 | 年龄 |
张明 | 男 | 18 |
李华 | 女 | 19 |
在上边的表格中,姓名、性别和年龄均可做为候选码,我们需要从中选出一个作为主码;
主码:用于标识由多个码中选出的作为唯一识别关系(其行没有重复)元组的码,而所有的码又称为候选码。
任何候选码(候选码)中的属性称为主属性,而不在任何码中的出现的属性称为非主属性;
候选码:某个关系变量的一组属性所组成的集合;其集合要满足两个条件:
1、这个属性集合始终能够确保在关系中能唯一标识元组;
2、在这个属性集合中找不出合适的子集能够满足条件;
满足第一个条件的属性集合称为超键,因此我们也可以把候选键定义为"最小超键",即不含有多余属性的超键。
我来讲下主属性和主键的区别,严格的来说:
主属性:指主键列,即主键由一列构成 ;
主键:能够唯一标识一个元组的属性或属性集,即可以由多列组成;
在教学中,大多实例都是主键由一列构成,所以也可以简单地说主属性与主键没有什么区别。
全码:关系模型的所有属性组是这个关系模式的候选码;
外码:如果FK是关系R的属性集,并且不是R的码,但是FK与关系R1的主码K1对应(是指属性集FK就是关系R1的码K1),则称FK是关系R的外码。其中,R是参照关系,R1是被参照关系;
大致关系:元组 > 全码 > 超键、候选键、非主属性;其中的 候选键 > 主键;
关系模式的规范化步骤
规范化程度越高,分解就越细,所得关系的数据冗杂就越小,异常情况也就越少,但同时也增大了系统对数据检索的开销,降低了数据检索的效率。系统只有对这些细分的关系进行自然连接,才能获取所需的信息,而连接操作所需的系统资源和开销是比较大的;因此,规范化程度越高的关系模式并非是最好的。
规范化中的范式有:1NF,2NF,3NF,BCNF(中文称为巴斯范式),4NF,5NF;
第一范式(1NF)
所谓第一范式,就是数据表的列不可再分。
我们来看下面数据表,对于选课列明显是可以再分的,所以它是违反第一范式的。
学号 | 姓名 | 选课 |
---|---|---|
10001 | 张三 | 数学,语文,英语 |
10002 | 李四 | 语文,英语 |
10003 | 王五 | 语文,英语,历史 |
第二范式(2NF)
第二范式首先要满足第一范式,并且表中非主键列不存在对主键的部分依赖(而是全部依赖)。
那么什么是部分依赖,什么又是全部依赖;请看下面例子:
学生选课表:
学号 | 课程 | 成绩 | 课程学分 |
10001 | 数学 | 100 | 6 |
10001 | 语文 | 90 | 2 |
10001 | 英语 | 85 | 3 |
10002 | 数学 | 90 | 6 |
10003 | 数学 | 99 | 6 |
10004 | 语文 | 89 | 2 |
表中主键为 (学号,课程),我们可以表示为 (学号,课程) —> (成绩,课程学分), 表示所有非主键列 (成绩,课程学分)都依赖于主键 (学号,课程)。 但是,表中还存在另外一个依赖:(课程)—>(课程学分)。这样非主键列 ‘课程学分‘ 依赖于部分主键列 ’课程‘(也就是部分依赖), 那全部依赖也就是其反之可得;所以上表是不满足第二范式的。
到了这里大家对关系数据库中的部分依赖和全部依赖的定义明白了没,其实我在这之前我也不太明白什么是部分依赖什么是全部依赖的;只要你想学,那你就会学会的;
其实大家对其中的某些知识带有这样的疑问???你怎么知道那个是主键;其实你要找主键,你就要对主键的定义清楚的同时也要有自己对表的判断(也就是关系数据库中的关系);
我们把它拆成如下2张表:
学生选课表:
学号 | 课程 | 成绩 |
10001 | 数学 | 100 |
10001 | 语文 | 90 |
10001 | 英语 | 85 |
10002 | 数学 | 90 |
10003 | 数学 | 99 |
10004 | 语文 | 89 |
课程信息表:
课程 | 课程学分 |
---|---|
数学 | 6 |
语文 | 3 |
英语 | 2 |
那么上面2个表,学生选课表主键为(学号,课程),课程信息表主键为(课程),表中所有非主键列都完全依赖主键。不仅符合第二范式,还符合第三范式。
再看这样一个学生信息表:
学号 | 姓名 | 性别 | 班级 | 班主任 |
---|---|---|---|---|
10001 | 张三 | 男 | 一班 | 小王 |
10002 | 李四 | 男 | 一班 | 小王 |
10003 | 王五 | 男 | 二班 | 小李 |
10004 | 张小三 | 男 | 二班 | 小李 |
上表中,主键为:(学号),所有字段 (姓名,性别,班级,班主任)都依赖与主键(学号),不存在对主键的部分依赖。所以是满足第二范式。
第三范式(3NF)
哈哈!到了解第三范式定义的时候啦!其要满足第二范式,并且表中的列不存在对非主键列的传递依赖。
哈——哈——哈???搞什么,刚学会部分依赖与全部依赖,又来一个传递依赖;“传递依赖”也就如其名,“传递”代表的意思也就是跟快递似,从这递到那;“依赖”代表的也就是关系的依赖,主键对非主键的依赖或非主键对主键的依赖;通过我的简单易懂的解释,明白了没童靴们;还没明白???——那就看下面的例子呗!
上面的学生信息表,虽然满足第二范式,所有字段都依赖主键(学号);但是,表中存在一个传递依赖:(学号)—>(班级) —>(班主任)。也就是说,(班主任)这个非主键列依赖与另外一个非主键列 (班级);哈哈,又到我出场啦!这里大家是不是又有点模糊啦!为什么从表中得出这么个非主键列依赖于那个非主键列,我们题目都没有提示或规定到这个关系???其实你看了上面的一个传递依赖:(学号)—>(班级) —>(班主任),是不是也就的合理啊!但是到了下面的(班主任)—>(班级)是不是心里就开始不踏实啦!心中想,如果没有第一个传递依赖的提示,那如何看出包含其中的依赖关系,并得出想要的答案呢!这里也就是个人是否细心的问题啦!回到上面的学生信息表,其不符号第三范式。
所以把这个表拆分成如下2个表,
学生信息表:
学号 | 姓名 | 性别 | 班级 |
---|---|---|---|
10001 | 张三 | 男 | 一班 |
10002 | 李四 | 男 | 一班 |
10003 | 王五 | 男 | 二班 |
10004 | 张小三 | 男 | 二班 |
班级信息表:
班级 | 班主任 |
---|---|
一班 | 小王 |
二班 | 小李 |
上面的2个表都符合第3范式;这样,对主键的传递依赖就消失了;其从第二范式修改为第三范式,也就是把第二范式中的依赖关系超过二个列的分开;每超过一个就形成一个表;
BCNF范式
大家是不是对其中的“T是决定因素而T不包含键”这句话不太理解;为什么T是决定因素???——>因为具有这样的传递关系:T—>J;那什么又是T不包含键???——>这我也没搞明白;
不过我把其定义写下:对3NF关系进行投影,将消除原关系中主属性对键的部分与传递依赖,得到一组BCNF关系;
如果有细心的家伙的话,其就会发现“候选键”这个关键词;其实它也就是候选码;
更高级别的范式
对应上面的班级信息表,完全可以设计成这样:
班级 | 班主任 | 班级人数 |
---|---|---|
一班 | 小王 | 40 |
二班 | 小李 | 45 |
这显然是符合第三范式的,所有列都依赖主键(班级),也不存在传递依赖。但是列(班级人数) 显然可以通过统计方法获得;出现在这张表,会造成维护困难或者不一致的情况。这就需要更高级别范式的约束。
规范化应满足的基本原则是由低到高,逐步规范,权衡利弊,适可而止。通常以满足第三范式为基本要求。