函数依赖与数据库设计的范式 - NOTE & BLOG
    函数依赖与数据库设计的范式
    11 March, 2024

    介绍函数依赖,以及数据库范式中的 1NF,2NF,3NF,BCNF 和 4NF。并且使用例子来解释它们的概念和联系。

    函数依赖

    在关系数据库中,函数依赖描述了关系模式中属性之间的依赖关系。如果给定一个关系 RR,属性集合 XX 的取值能够唯一确定(通过条件查找、作为函数参数查找等)属性集合 YY 的一条取值,那么我们说 YY 函数依赖于 XX,通常用符号 XYX \rightarrow Y 来表示。

    具体来说,如果对于关系 RR 中的每一条记录,如果两个记录在属性集合 XX 上的取值相同,那么它们在属性集合 YY 上的取值也必须相同,那么我们称 YY 函数依赖于 XX

    例如,假设我们有一个关系 RR 包含属性集合 {A,B,C}\{ A,B,C \},其中属性 AA 的取值能够唯一确定属性 BB 的取值,即 ABA \rightarrow B ,那么我们称属性 BB 函数依赖于属性 AA

    函数依赖是关系数据库设计中的重要概念,它有助于理解数据之间的关系,规范化数据库设计以减少冗余数据,同时确保数据的一致性和完整性。

    而函数依赖也分为平凡函数依赖和非平凡函数依赖。

    XYX \rightarrow Y,且 YXY \subseteq X,那么称 XYX \rightarrow Y 为平凡函数依赖。否则为非平凡函数依赖。

    对于函数依赖,XXYY的依赖关系,也可以具体划分为部分函数依赖、完全函数依赖和传递函数依赖。

    • 部分函数依赖:设 X,YX,Y 是关系 RR 的两个属性集合,若XYX→YXXX' \subsetneq X,使得 XY\exist{X’}→Y,则称 YY 部分函数依赖于 XX。专门记作 XPYX \overset{P}{\rightarrow} Y。换句话说,部分函数依赖意味着某些属性可以被移除而不影响映射依赖。

    举个例子:学生基本信息表 RR 中(学号,护照号码,姓名)当然学号属性取值是唯一的,在 RR 关系中,(学号,护照号码)→(姓名),(学号)→(姓名),(护照号码)→(姓名);所以姓名部分函数依赖于(学号,护照号码);

    • 完全函数依赖:设 X,YX,Y 是关系 RR 的两个属性集合,若XYX→Y, XXX' \subsetneq X,使得 XY\forall{X’}→Y,则称 YY 完全函数依赖于 XX。专门记作 XFYX \overset{F}{\rightarrow} Y 。换句话说,对于完全函数依赖来说,没有多余的属性可以被删除,否则将无法保持映射依赖的性质。

    例子:学生基本信息表 RR(学号,班级,姓名)假设不同的班级学号有相同的,班级内学号不能相同,在 RR 关系中,(学号,班级)→(姓名),但是(学号)→(姓名) 不成立,(班级)→(姓名) 不成立,所以姓名完全函数依赖与(学号,班级);

    • 传递函数依赖:设 X,Y,ZX,Y,Z 是关系 RR 中互不相同的属性集合,若 XY(YX)X→Y(Y \cancel{\rightarrow} X), 有YZ\forall{Y}→Z,则称 ZZ 传递函数依赖于 XX。这意味着ZZ间接地依赖于XX

    例子:在关系 RR (学号,宿舍,费用) 中,(学号)→(宿舍),宿舍!=学号,(宿舍)→(费用),费用!=宿舍,所以符合传递函数的要求;

    多值依赖

    以上介绍了函数依赖,但函数依赖其实是多值依赖的一个特例,多值依赖是函数依赖的扩展。

    R(U)R(U) 是一个属性集 UU 上的一个关系模式,X,YX,YZZUU 的子集,并且 ZUXYZ=U-X-Y ,多值依赖 XYX\twoheadrightarrow Y 成立当且仅当对 RR 的任一关系rrrr(XZ)(X,Z) 上的每个值对应一组 YY 的值,这组值仅仅决定于 XX 值而与 ZZ 值无关。

    假设我们有一个关系模式 RR,包含属性集合{Student,Course,Textbook}\{Student,Course,Textbook\},表示学生所选的课程以及使用的教材。如果一个学生在一门课程上使用多种教材,而且学生和课程的组合能够唯一确定所使用的教材,但是学生和课程之间的组合是相互独立的,那么我们就有了一个多值依赖。

    假设有如下关系实例:

    StudentCourseTextbook
    Alice数学微积分
    Alice数学线性代数
    Alice物理力学
    Bob数学微积分

    在这个例子中,教材的选择取决于学生和课程的组合。例如,Alice 在数学课上使用的教材包括微积分和线性代数,而在物理课上使用的教材是力学。而教材是否选取线性代数和微积分,只和课程是否为数学有关。 这里就存在一个多值依赖,因为学生和课程的组合能够唯一确定教材集,但学生和课程之间的关系是相互独立的,教材与课程却不是独立的,教材取决于课程,但一个课程可以有多个教材。

    所以在这里就存在一个多值依赖关系 CourseTextbookCourse \twoheadrightarrow Textbook

    • KKR<U,F>R<U,F>中的属性或者属性组合,且KFUK \overset{F}{\rightarrow} U,则 KKRR 的候选码。
    • 若候选码多于一个,则可以选定其中一个称为主码。
    • 任何一个包含候选码的属性集合称为主属性。否则为非主属性。
    • 如果整个属性集合都是候选码,则称这个属性集合为全码。
    • 主码和候选码均简称为码。

    数据库的范式

    1NF

    1NF1NF(第一范式)是关系数据库中的基本范式之一,它要求关系模式中的每个属性都是原子的,即属性不可再分。换句话说,关系模式中的每个属性都应该是单值的,而不是包含多个值的集合或列表。

    具体来说,1NF1NF 要求关系模式中的每个单元格都只包含一个值,而不是多个值或复杂的数据类型。这样做有助于确保数据的原子性,简化数据的处理和查询。

    例如,假设有一个学生表,其中包含姓名和电话号码。如果电话号码以逗号分隔的形式存储多个号码,那么这个表就不符合 1NF1NF。为了符合 1NF1NF,应该将电话号码拆分成单独的属性,每个属性只包含一个电话号码。

    2NF

    2NF2NF(第二范式)是关系数据库中的范式之一,它建立在第一范式(1NF1NF)的基础上。2NF2NF 要求关系模式中的每个非主属性都完全依赖于候选码,而不是部分依赖于候选码。

    具体来说,如果关系模式中的候选键有多个属性,那么每个非主属性都应该依赖于这些属性的所有组合,而不是只依赖于其中的一部分。

    假设我们有一个关系模式包含以下属性:学生 ID(StudentID)、课程 ID(CourseID)、课程名称(CourseName)、学生姓名(StudentName)以及成绩(Grade)。在这个关系模式中,(StudentID,CourseID)是候选码,代表了学生选课的情况。

    StudentIDCourseIDCourseNameStudentNameGrade
    101001数学AliceA
    101002物理AliceB
    102001数学BobA
    102003化学BobC

    在这个例子中,学生姓名(StudentName)属性是非主属性,依赖于部分候选码(StudentID),而不是所有候选码(StudentID,CourseID)。例如,学生 Alice 的姓名只与学生 ID 101 相关联,而与选课情况无关。

    因此,该关系模式不符合第二范式(2NF2NF)。要符合 2NF2NF,我们应该将学生姓名从这个关系模式中移除,并将其放在一个单独的表中,该表的候选键是 StudentIDStudentID。这样,学生姓名就完全依赖于候选码,而不是部分依赖于候选码。

    3NF

    设关系模式 R<U,F>1NFR<U,F> \in 1NF,且不存在码 XX,属性组 YY 和非候选码 ZZ,使得XY,YZ,YXX \rightarrow Y, Y \rightarrow Z, Y \cancel{\rightarrow} X成立,则属于 3NF3NF 。换句话说,如果一个关系属于 2NF2NF,且每个非候选码不传递依赖于候选码,这种关系是 3NF3NF

    让我们继续考虑上面学校的学生选课情况的例子,并尝试符合第三范式(3NF3NF)。

    在这个例子中,我们已经将学生姓名从主表中移除,并将其放在了一个单独的表中,如下所示:

    学生表:

    StudentIDStudentName
    101Alice
    102Bob

    选课表:

    StudentIDCourseIDGrade
    101001A
    101002B
    102001A
    102003C

    现在,我们来看一下是否符合 3NF3NF。在这个关系模式中,我们有一个传递依赖关系:学生 ID(StudentID)确定了学生姓名(StudentName),而课程 ID(CourseID)确定了学生 ID(StudentID)。因此,存在一个传递函数依赖:CourseIDStudentNameCourseID \rightarrow StudentName

    为了符合 3NF3NF,我们需要消除这个传递依赖。一种方法是创建一个新的表,将 CourseIDCourseIDStudentIDStudentID 映射到 StudentNameStudentName,以消除这种传递依赖关系。这样,我们就能确保每个非主属性完全依赖于主键。

    学生选课关系表:

    StudentIDCourseIDGrade
    101001A
    101002B
    102001A
    102003C

    学生表:

    StudentIDStudentName
    101Alice
    102Bob

    课程表:

    CourseIDCourseName
    001Mathematics
    002Physics
    003Chemistry

    现在,每个表都符合第三范式(3NF3NF)。学生表和课程表都与学生选课关系表保持关联,没有了传递依赖关系。

    BCNF

    BCNFBCNF(Boyce-Codd Normal Form)是关系数据库中的一种更严格的范式,它是在第三范式(3NF3NF)的基础上进一步规范化关系模式的结果。BCNFBCNF 要求每一条非平凡函数依赖关系(非平凡的 XYX \rightarrow Y,其中 YY 不是 XX 的超集)都是由这个关系中的码决定的。

    换句话说,如果 RR 是一个关系模式,XYX \rightarrow YRR 的一个非平凡函数依赖,而 XX 不包含候选键,那么 RR 就不符合 BCNFBCNF,也就是说,每一个决定因素都必须包含码。

    举个例子,现在有一张排课表,记载学生 ID,课程 ID 和教师 ID。一位老师只教一门课,一门课可以由多个老师教,每一名学生选定某门课,就对应一个固定教师。假设候选码为学生 ID,课程 ID。则可以列出以下函数关系:

    • (StudentID,CourseID)TeacherID(StudentID,CourseID) \rightarrow TeacherID
    • (StudentID,TeacherID)CourseID(StudentID,TeacherID) \rightarrow CourseID
    • TeacherIDCourseIDTeacherID \rightarrow CourseID

    这个关系就不符合 BCNFBCNF 因为我们发现,第三条函数依赖关系,TeacherIDTeacherID不包含任何码。而第一二条都有码。

    4NF

    4NF4NF是数据库规范化的一种形式,它是在BCNFBCNF的基础上进一步强调了多值依赖的消除。一个关系模式在满足4NF4NF时,除了满足BCNFBCNF的要求外,还要求不存在任何非平凡多值依赖。非平凡多值依赖是指左部和右部都不是关系的超码。

    让我们考虑一个符合 BCNF 但不符合 4NF 的例子。

    假设我们有一个关系模式 RR ,包含学生(Student)、课程(Course)、成绩(Grade)和教师(Teacher)这四个属性,并且存在以下函数依赖:

    1. (Student,Course)Grade(Student,Course) \rightarrow Grade
    2. CourseTeacherCourse \rightarrow Teacher
    3. StudentTeacherStudent \twoheadrightarrow Teacher

    假设关系模式中的候选键是Student,CourseStudent,Course

    上面符合 BCNFBCNF ,因为是每一个函数依赖都是由候选键确定的。

    但是,不符合 4NF4NF 的原因是存在第三条的多值依赖。这是因为每个学生可能会上多门课程,而每门课程可能会有不同的教师。

    因此,尽管这个关系模式符合 BCNFBCNF,但不符合 4NF4NF

    联系

    1NF1NF4NF4NF 的认识是递进关系。它们之间的联系如下:

    • 1NF1NF 消除非主属性对码的部分函数依赖得到 2NF2NF
    • 2NF2NF 消除非主属性对码的传递函数依赖得到 3NF3NF
    • 3NF3NF 消除主属性对码的部分和传递函数依赖得到 BCNFBCNF
    • BCNFBCNF 消除非平凡且函数依赖的多值依赖得到 4NF4NF

    凡有所学,皆成性格

    Share with the post url and description