函数依赖
在关系数据库中,函数依赖描述了关系模式中属性之间的依赖关系。如果给定一个关系 ,属性集合 的取值能够唯一确定(通过条件查找、作为函数参数查找等)属性集合 的一条取值,那么我们说 函数依赖于 ,通常用符号 来表示。
具体来说,如果对于关系 中的每一条记录,如果两个记录在属性集合 上的取值相同,那么它们在属性集合 上的取值也必须相同,那么我们称 函数依赖于 。
例如,假设我们有一个关系 包含属性集合 ,其中属性 的取值能够唯一确定属性 的取值,即 ,那么我们称属性 函数依赖于属性 。
函数依赖是关系数据库设计中的重要概念,它有助于理解数据之间的关系,规范化数据库设计以减少冗余数据,同时确保数据的一致性和完整性。
而函数依赖也分为平凡函数依赖和非平凡函数依赖。
若 ,且 ,那么称 为平凡函数依赖。否则为非平凡函数依赖。
对于函数依赖,与的依赖关系,也可以具体划分为部分函数依赖、完全函数依赖和传递函数依赖。
- 部分函数依赖:设 是关系 的两个属性集合,若,,使得 ,则称 部分函数依赖于 。专门记作 。换句话说,部分函数依赖意味着某些属性可以被移除而不影响映射依赖。
举个例子:学生基本信息表 中(学号,护照号码,姓名)当然学号属性取值是唯一的,在 关系中,(学号,护照号码)→(姓名),(学号)→(姓名),(护照号码)→(姓名);所以姓名部分函数依赖于(学号,护照号码);
- 完全函数依赖:设 是关系 的两个属性集合,若, ,使得 ,则称 完全函数依赖于 。专门记作 。换句话说,对于完全函数依赖来说,没有多余的属性可以被删除,否则将无法保持映射依赖的性质。
例子:学生基本信息表 (学号,班级,姓名)假设不同的班级学号有相同的,班级内学号不能相同,在 关系中,(学号,班级)→(姓名),但是(学号)→(姓名) 不成立,(班级)→(姓名) 不成立,所以姓名完全函数依赖与(学号,班级);
- 传递函数依赖:设 是关系 中互不相同的属性集合,若 , 有,则称 传递函数依赖于 。这意味着间接地依赖于。
例子:在关系 (学号,宿舍,费用) 中,(学号)→(宿舍),宿舍!=学号,(宿舍)→(费用),费用!=宿舍,所以符合传递函数的要求;
多值依赖
以上介绍了函数依赖,但函数依赖其实是多值依赖的一个特例,多值依赖是函数依赖的扩展。
设 是一个属性集 上的一个关系模式, 和 是 的子集,并且 ,多值依赖 成立当且仅当对 的任一关系, 在 上的每个值对应一组 的值,这组值仅仅决定于 值而与 值无关。
假设我们有一个关系模式 ,包含属性集合,表示学生所选的课程以及使用的教材。如果一个学生在一门课程上使用多种教材,而且学生和课程的组合能够唯一确定所使用的教材,但是学生和课程之间的组合是相互独立的,那么我们就有了一个多值依赖。
假设有如下关系实例:
在这个例子中,教材的选择取决于学生和课程的组合。例如,Alice 在数学课上使用的教材包括微积分和线性代数,而在物理课上使用的教材是力学。而教材是否选取线性代数和微积分,只和课程是否为数学有关。 这里就存在一个多值依赖,因为学生和课程的组合能够唯一确定教材集,但学生和课程之间的关系是相互独立的,教材与课程却不是独立的,教材取决于课程,但一个课程可以有多个教材。
所以在这里就存在一个多值依赖关系
码
- 设 为 中的属性或者属性组合,且,则 为 的候选码。
- 若候选码多于一个,则可以选定其中一个称为主码。
- 任何一个包含候选码的属性集合称为主属性。否则为非主属性。
- 如果整个属性集合都是候选码,则称这个属性集合为全码。
- 主码和候选码均简称为码。
数据库的范式
1NF
(第一范式)是关系数据库中的基本范式之一,它要求关系模式中的每个属性都是原子的,即属性不可再分。换句话说,关系模式中的每个属性都应该是单值的,而不是包含多个值的集合或列表。
具体来说, 要求关系模式中的每个单元格都只包含一个值,而不是多个值或复杂的数据类型。这样做有助于确保数据的原子性,简化数据的处理和查询。
例如,假设有一个学生表,其中包含姓名和电话号码。如果电话号码以逗号分隔的形式存储多个号码,那么这个表就不符合 。为了符合 ,应该将电话号码拆分成单独的属性,每个属性只包含一个电话号码。
2NF
(第二范式)是关系数据库中的范式之一,它建立在第一范式()的基础上。 要求关系模式中的每个非主属性都完全依赖于候选码,而不是部分依赖于候选码。
具体来说,如果关系模式中的候选键有多个属性,那么每个非主属性都应该依赖于这些属性的所有组合,而不是只依赖于其中的一部分。
假设我们有一个关系模式包含以下属性:学生 ID(StudentID)、课程 ID(CourseID)、课程名称(CourseName)、学生姓名(StudentName)以及成绩(Grade)。在这个关系模式中,(StudentID,CourseID)是候选码,代表了学生选课的情况。
在这个例子中,学生姓名(StudentName)属性是非主属性,依赖于部分候选码(StudentID),而不是所有候选码(StudentID,CourseID)。例如,学生 Alice 的姓名只与学生 ID 101 相关联,而与选课情况无关。
因此,该关系模式不符合第二范式()。要符合 ,我们应该将学生姓名从这个关系模式中移除,并将其放在一个单独的表中,该表的候选键是 。这样,学生姓名就完全依赖于候选码,而不是部分依赖于候选码。
3NF
设关系模式 ,且不存在码 ,属性组 和非候选码 ,使得成立,则属于 。换句话说,如果一个关系属于 ,且每个非候选码不传递依赖于候选码,这种关系是 。
让我们继续考虑上面学校的学生选课情况的例子,并尝试符合第三范式()。
在这个例子中,我们已经将学生姓名从主表中移除,并将其放在了一个单独的表中,如下所示:
学生表:
选课表:
现在,我们来看一下是否符合 。在这个关系模式中,我们有一个传递依赖关系:学生 ID(StudentID)确定了学生姓名(StudentName),而课程 ID(CourseID)确定了学生 ID(StudentID)。因此,存在一个传递函数依赖:。
为了符合 ,我们需要消除这个传递依赖。一种方法是创建一个新的表,将 和 映射到 ,以消除这种传递依赖关系。这样,我们就能确保每个非主属性完全依赖于主键。
学生选课关系表:
学生表:
课程表:
现在,每个表都符合第三范式()。学生表和课程表都与学生选课关系表保持关联,没有了传递依赖关系。
BCNF
(Boyce-Codd Normal Form)是关系数据库中的一种更严格的范式,它是在第三范式()的基础上进一步规范化关系模式的结果。 要求每一条非平凡函数依赖关系(非平凡的 ,其中 不是 的超集)都是由这个关系中的码决定的。
换句话说,如果 是一个关系模式, 是 的一个非平凡函数依赖,而 不包含候选键,那么 就不符合 ,也就是说,每一个决定因素都必须包含码。
举个例子,现在有一张排课表,记载学生 ID,课程 ID 和教师 ID。一位老师只教一门课,一门课可以由多个老师教,每一名学生选定某门课,就对应一个固定教师。假设候选码为学生 ID,课程 ID。则可以列出以下函数关系:
这个关系就不符合 因为我们发现,第三条函数依赖关系,不包含任何码。而第一二条都有码。
4NF
是数据库规范化的一种形式,它是在的基础上进一步强调了多值依赖的消除。一个关系模式在满足时,除了满足的要求外,还要求不存在任何非平凡多值依赖。非平凡多值依赖是指左部和右部都不是关系的超码。
让我们考虑一个符合 BCNF 但不符合 4NF 的例子。
假设我们有一个关系模式 ,包含学生(Student)、课程(Course)、成绩(Grade)和教师(Teacher)这四个属性,并且存在以下函数依赖:
假设关系模式中的候选键是。
上面符合 ,因为是每一个函数依赖都是由候选键确定的。
但是,不符合 的原因是存在第三条的多值依赖。这是因为每个学生可能会上多门课程,而每门课程可能会有不同的教师。
因此,尽管这个关系模式符合 ,但不符合 。
联系
从 到 的认识是递进关系。它们之间的联系如下:
- 消除非主属性对码的部分函数依赖得到
- 消除非主属性对码的传递函数依赖得到
- 消除主属性对码的部分和传递函数依赖得到
- 消除非平凡且函数依赖的多值依赖得到