R:关系名
U:组成该关系的属性名集合
D∶属性组U中属性所来自的域
DOM:属性
到域的映射
F:属性组U上的一组数据依赖
由于D、DOM对模式设计的关系不大,这里把关系模式简化为一个三元组:
R,当且仅当U上的一个关系P满足F时,R称为关系模式R的一个关系。
1、关系数据库设计的核心:关系模式的设计。
2、关系模式的设计目标:按照一定的原则从数量众多而又相互关联的数据中,构造出一组l既能较好地反映现实世界,而又有良好的操作性能的关系模式。
需求分析—〉概念结构设计(E-R图)—〉逻辑结构设计(关系模式设计)—)物理结构设计
数据依赖的类型
如果X→Y,且YSX,则X→Y称为非平凡函数依赖。
若YC X,则称X→Y为平凡函数依赖。由于Y CX时,一定有X→Y,平凡函数依赖必然成立,没有意义,所以一般所说的函数依赖总是指非平凡函数依赖。
完全函数依赖分析
成绩依赖于学号和课程号两个字段的组合;但只知道学号无法确定成绩,同理只知道课程号也无法确定成绩;只有学号和课程号组合在一起才能标识哪个学生哪门课程的成绩;
因此(学号,课程号)---->成绩 是“完全函数依赖”。
部分函数依赖分析
姓名、性别和班级三个属性只依赖于主键中的学号,与“课程号”无关。 因此(学号,课程号)——>姓名 是“部分函数依赖” (学号,课程号)——>性别 是“部分函数依赖” (学号,课程号)——>班级 是“部分函数依赖”
课程名和学时数只依赖于课程号,
因此(学号,课程号)----->课程名是“部分函数依赖”
传递函数依赖分析
班主任依赖于班级,与学号无关,与课程号也无关
又因班级依赖于学号,所以班主任间接依赖于学号
因此,(学号,课程号)----->班主任是“传递函数依赖”
主码 候选码 码
ps:元组理解为一张表的某一行,属性理解为一张表的某一列,属性名就是列的名字(字段)。
1(码):码是可以确定一个元组的所有信息的属性名或属性名组。
例如在 { a, b, c, d } 中,
假设知道 a 的值就能确定 a, b, c, d 的值,
假设知道 c, d 的值就可以确定 a, b, c, d 的值,
那么 { a } 就是码,{ c, d } 就是码。
并且 { a, b }, { a, c }, { a, b, c }, { a, b, c, d } 等也都是码,因为它们也可以确定一个元组的所有值,即使很多余。
2(候选码):候选码的真子集中不存在码,候选码可以有多个。
就上面的例子而言,{ a } 是候选码,{ c, d } 是候选码,因为它们的真子集中不存在码。
而诸如 { a, b } 并不是候选码,因为它的真子集中含有 { a }, 且 { a } 是码。
3(主码):主码就是主键的意思,主码是任意一个候选码。
还是上面的例子,主码是候选码 { a }, { c, d } 中的其中一个。
既可以是 { a }, 也可以是 { c, d }。
更清晰的讲解见博客https://blog.csdn.net/sumaliqinghua/article/details/85872446?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522162709035016780269848416%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=162709035016780269848416&biz_id=0&spm=1018.2226.3001.4187
范式这里就不说课本、网上那些晦涩难懂的概念了。
1NF:无重复的列(数据库表中的每一列都是不可分割的基本数据项)
2NF:满足1NF且非主键列都完全函数依赖于主键。
3NF:满足2NF且非主属性列都不传递依赖于主键。
BCNF:满足3NF且不允许主键的一部分被另一部分或其它部分所决定(即满足3范式,并且主属性之间没有依赖关系)。
习题会讲解的非常详细,请一定认真看。
题目:设有关系模式 R(职工名,项目名,工资,部门名,部门经理)
如果规定,每个职工可参加多个项目,各领一份工资;每个项目
只属于一个部门管理;每个部门只有一个经理。
分析
依赖关系我们使用 → 表示,可以理解为指向谁就代表可以推出谁,或者归谁管。
比如在这里,职工名和项目名合在一起可以推出工资是多少就可以表示为:(职工名,项目名)→工资;
再者,项目归部门管,可以表示为:项目名→部门名;部门归部门经理管可以表示为:部门名→部门经理。
好了,到现在为止我们就已经将第一问中的函数依赖写出来了,我们再来捋一下:
部门经理依赖于部门,也就是说要先确定部门才能确定部门经理,所以是依赖关系;
而部门依赖于项目,要先确定项目才能确定部门;
工资依赖于两个属性:职工名和项目名。
那么主码又是什么呢?
主码也叫主键,是指可以通过它唯一确定一条数据的这样一个属性。
比如学号就可以做主键,因为一个学号对应一个学生。
那么这里的主键是什么呢?
我们就要找通过谁可以唯一确定一条记录,项目名肯定不行,因为他和职工名一起才可以确定工资,那职工名肯定也不行,但是把它们合在一起就可以了,这样就可以确定唯一的一条记录。
所以,主键为(职工名,项目名)。
所以答案就是:
函数依赖关系: (职工名,项目名)→工资 项目名→部门名 部门名→部门经理 主键为(职工名,项目名)。
来看第二问:说明 R 不是 2NF 模式的理由,并把 R 分解成 2NF 。
2NF 是什么呢?
就是一种规范,他规定不能存在部分依赖,部分依赖是啥意思呢?就是我们只看依赖于主键的属性,这里有工资和部门名,但是他们两个的区别是工资对应的全部的主键,也就是两个值,但是部门名只依赖于项目名,少了一个,所以是部分依赖。
所以他存在了部分依赖就不是 2NF 模式了,那么怎么把它化成 2NF 呢?
一般我们只能通过分解的方式来消除,就是把一个关系拆成两个关系:
R1(项目名,部门名,部门经理)
R2(职工名,项目名,工资)
这样每个关系中就不存在部分依赖了。
来看第三问:进而将 R 分解成 3NF ,并说明理由。
那么 3NF 又是啥
我们先来观察上面那个 2NF
的关系,发现有一个关系R1(项目名,部门名,部门经理),他比较特殊,就是项目名→部门名,部门名→部门经理,他是连续的,就是传递性的依赖关系,3NF
就是要去掉这种依赖关系。
那么我们来去掉可得:
可以把 R1 再分成两个关系:
R11(项目名,部门名)
R12(部门名,部门经理)