关系模式与数据依赖

一个关系模式应当是一个五元组:

R(U, D, DOM, F)

  • 关系名R是符号化的元组语义

  • U为一组属性

  • D为属性组U中的属性所来自的域

  • DOM为属性到域的映射

  • F为属性组上的一组数据依赖

由于D、DOM与模式设计关系不大,故在模式设计阶段,可以写成三元组 R<U,F>, 当且仅当U上的一个关系r满足F时,r称为关系模式R<U, F>的一个关系。

作为一个二维表,关系要符合一个最基本的条件:每个分量必须是不可分的数据项。满足这一条件的关系模式就属于第一范式(1NF)

数据依赖是一个关系内部属性与属性之间的一种约束关系,它是通过属性间值的相等与否体现出来的数据间的相关联系,是现实世界属性间相互联系的抽象,是数据内在的性质,是语义的体现。

数据依赖中,最重要的是函数依赖和多值依赖。

  • 函数依赖:在关系模式中,如果属性A的值确定后,属性B的值也随之确定,那么称属性B函数依赖于属性A。简单地说,函数依赖描述的是一对一的依赖关系。

  • 多值依赖:在关系模式中,如果属性组A的值确定后,属性组B的值与属性组C的值之间存在一定的依赖关系,但并非一对一的,而是可能存在多对多的关系,那么称属性组B多值依赖于属性组A。多值依赖描述的是一对多的依赖关系。

性质:

  • 函数依赖:具有自反性、增广性和传递性。如果A→B且B→C,那么A→C。此外,函数依赖的有效性与属性集的范围无关,即只要在某一属性集上成立,那么在包含该属性集的任何超集上也都成立。

  • 多值依赖:具有对称性,即如果X→→Y,则X→→Z(其中Z是除X、Y之外的其他属性)。但多值依赖的有效性与属性集的范围有关,即如果X→→Y在某一属性集U上成立,那么在U的子集W上并不一定成立。此外,多值依赖是全模式的依赖关系,涉及所有属性。

举个栗子

  • 函数依赖示例:在员工关系中,如果员工的员工号(A)确定,那么其姓名(B)也确定,即A→B。

  • 多值依赖示例:在订单关系中,如果客户ID(A)确定,那么该客户所下的订单号(B)与订单中的商品ID(C)之间存在多值依赖关系,即A→→BC。因为同一个客户可以下多个订单,每个订单中可以包含多个商品。

关系模式的常见问题

数据冗余

数据冗余是指数据在多个地方被重复存储。这会导致存储空间的浪费,并可能增加数据维护的复杂性。例如,在一个非规范化的数据库中,员工的信息可能同时在“员工”表和“订单”表中被重复存储。

更新异常

更新异常是指当需要更改某个数据时,可能需要在多个地方进行更改,这可能导致不一致性。例如,如果员工的信息(如电话号码)在多个表中被重复存储,那么更改电话号码就需要更新所有相关的表,这既繁琐又容易出错。

插入异常

插入异常是指当无法插入符合关系模式要求的元组时发生的情况。这通常是因为违反了某些完整性约束或外键约束。但是,在规范化不足的情况下,插入异常通常指的是因为缺少某些非主属性而无法插入完整的记录。例如,在一个非规范化的数据库中,如果尝试插入一个新的订单但没有指定员工信息(尽管该信息对于订单来说不是必需的),则可能会遇到插入异常。

删除异常

删除异常是指当删除某个元组时,会意外地删除不应该被删除的数据。这通常发生在包含冗余数据的非规范化数据库中。例如,如果一个员工负责多个订单,并且员工信息在“员工”表和“订单”表中都被存储,那么删除“员工”表中的某个员工记录可能会导致与该员工相关的所有订单信息也被删除,即使这些订单仍然需要被保留。

一个好的关系模式应当不会发生插入异常、删除异常和更新异常,数据冗余应尽可能少。

规范化

函数依赖

函数依赖:设R(U)是属性集U上的关系模式,X,Y是U的子集。若对于R(U)上的任意一个可能的关系r,r中不可能存在两个元组在X上的属性值相等,而在Y上的属性值不等,则称X函数确定Y或Y函数依赖于X,记作X→Y。

注意:函数依赖不是指关系模式R的某个或某些关系满足的约束条件,而是指R的一切关系均要满足的约束条件。

  • X→Y,但Y不属于X,则称非平凡的函数依赖。

  • X→Y,但Y属于X,则称平凡的函数依赖。

  • X→Y,则称X为函数依赖的决定属性组,也称为决定因素。

完全函数依赖指的是在一个关系中,某个非主属性数据项依赖于全部关键字。具体来说,如果非主属性B函数依赖于构成某个候选关键字的一组主属性A,而且A的任何一个真子集不能被B函数依赖,则称B完全函数依赖于A。例如,在成绩表(学号,课程号,成绩)的关系中,完全函数依赖的例子是(学号,课程号)→成绩,即成绩完全依赖于学号和课程号的组合。

部分函数依赖则是指在一个关系中,某个非主属性数据项依赖于部分关键字。具体来说,如果X→Y(X决定Y),并且存在X的一个真子集X0,使得X0→Y也成立,则称Y对X部分函数依赖。也就是说,如果非主属性B函数依赖于构成某个候选关键字的一组主属性A的真子集,则称B部分函数依赖于A。例如,在成绩表中,如果学号或课程号单独能决定某个学生的某个成绩,则称成绩对学号或课程号部分函数依赖。

  1. 候选码(Candidate Key)

    • 定义:关系中的一个属性或属性组的值能够唯一地标识一个元组,且它的子集不能唯一地标识一个元组,则称这个属性或属性组为候选码。

    • 例子:在学生实体中,“学号”是能唯一区分学生实体的,所以“学号”是一个候选码。如果“姓名”和“班级”的组合也能唯一标识一个学生,那么{姓名,班级}也是一个候选码。

  2. 超码(Superkey)

    • 定义:一个或多个属性的集合,这些属性的组合可以在一个实体集中唯一地标识一个实体。超码可能包含多余的属性。

    • 例子:在上述学生实体的例子中,虽然“学号”是一个候选码,但“学号”和“姓名”的组合(即使“姓名”不是唯一的)也是一个超码,因为它仍然可以唯一标识一个学生。

  3. 主码(Primary Key)

    • 定义:主码是从候选码中选取的一个用于唯一标识元组的属性或属性组。一个关系只能有一个主码。

    • 例子:在上述学生实体的例子中,我们可以选择“学号”作为主码。

  4. 主属性(Prime Attribute)

    • 定义:包含在任一候选码中的属性称为主属性。

    • 例子:在关系“工人(工号,身份证号,姓名,性别,部门)”中,工号和身份证号都是候选码,因此它们都是主属性。

  5. 非主属性(Non-Prime Attribute)

    • 定义:不包含在任何一个候选码中的属性称为非主属性。

    • 例子:在关系“工人(工号,身份证号,姓名,性别,部门)”中,姓名、性别和部门都是非主属性。

  6. 全码(All-Key)

    • 定义:如果关系模式R的所有属性组组成该关系模式的候选码,则称为全码。即所有属性当作一个码。

    • 例子:关系模式R(T,C,S),其中T表示教师,C表示课程,S表示学生。如果T、C、S的组合能唯一标识一个元组,并且没有其他更小的属性组合能做到这一点,那么{T,C,S}就是一个全码。

范式

关系数据库中的关系是要满足一定要求的,满足不同程度要求的为不同的范式。

在函数依赖范畴内

1NF(第一范式)

定义:关系模式R的每个属性都是不可再分的数据项。

详细解释

  • 原子性:1NF的核心是确保数据库表中的字段(或属性)都是“原子”的,即不可再分。例如,一个“地址”字段不应该包含“街道”、“城市”和“国家”等多个子属性。这些子属性应该被拆分为独立的字段。

  • 消除重复列:1NF还禁止在表中出现重复的列。

  • 目的:确保数据的原子性,减少数据冗余和更新异常。

2NF(第二范式)

定义:关系模式R属于1NF,且R的所有非主属性都完全函数依赖于R的候选键。

详细解释

  • 完全函数依赖:在2NF中,非主属性必须完全依赖于整个候选键,而不是候选键的一部分。这意味着,如果候选键由多个属性组成,那么非主属性不能仅依赖于这些属性中的一个或几个。

  • 消除部分依赖:通过消除部分函数依赖,2NF减少了数据冗余和更新异常。

  • 例子:考虑一个包含“学号”、“课程号”和“成绩”的关系。在这个关系中,“学号”和“课程号”的组合构成候选键。因为“成绩”完全依赖于这个组合,而不是单独依赖于“学号”或“课程号”,所以这个关系满足2NF。

3NF(第三范式)

定义:关系模式R属于2NF,且R的所有非主属性对R的任何候选键都不存在传递函数依赖。

详细解释

  • 传递函数依赖:如果A→B且B→C(但A不直接→C),则称C对A存在传递函数依赖。在3NF中,这种传递依赖是不被允许的。

  • 减少冗余:通过消除传递函数依赖,3NF进一步减少了数据冗余和更新异常。

  • 例子:考虑一个包含“学号”、“姓名”和“系部”的关系。在这个关系中,“学号”是候选键。虽然“姓名”和“系部”都依赖于“学号”,但“系部”并不直接依赖于“姓名”。然而,如果我们允许“系部”通过“姓名”传递依赖于“学号”,就可能导致数据冗余和更新异常。因此,为了满足3NF,我们应该将“系部”信息存储在一个单独的关系中,并通过“学号”与原始关系关联。

BCNF(巴斯-科德范式)

定义:关系模式R属于1NF,且对于R的每个函数依赖X→Y(Y不是X的子集),X都是R的候选键。

详细解释

  • 候选键的要求:在BCNF中,对于任何非平凡的函数依赖X→Y(其中Y不是X的子集),X都必须是候选键。这确保了数据库表中的所有属性都直接依赖于主键(或候选键),从而消除了任何形式的数据冗余和更新异常。

  • 与3NF的区别:虽然BCNF在某些方面类似于3NF(例如它们都试图消除数据冗余和更新异常),但BCNF对候选键的要求更加严格。在3NF中,只要非主属性不传递依赖于主键即可;而在BCNF中,非主属性必须直接依赖于整个候选键。

  • 适用场景:BCNF通常用于需要高度数据一致性和完整性的数据库设计中。然而,由于其严格的要求,有时可能导致数据库设计过于复杂或难以实现。因此,在实际应用中,通常根据具体需求在1NF、2NF、3NF和BCNF之间进行权衡和选择。

多值依赖

多值依赖是在关系型数据库设计中用于描述属性之间复杂依赖关系的一个概念。在关系模式中,函数依赖(Functional Dependency)描述的是属性值之间的一对一或一对零的关系,即一个属性(或属性组)的值能够唯一确定另一个属性(或属性组)的值。然而,函数依赖无法表示属性值之间的一对多关系,这时就需要用到多值依赖。

多值依赖描述的是当一组属性(X)的值确定时,另一组属性(Y)可以有多个值与之对应,而这些值并不直接依赖于第三组属性(Z)。这里的“不直接依赖于Z”意味着Y的值仅由X的值决定,与Z的值无关。

它具有如下性质:

  • 对称性:如果X→→Y成立,那么X也必然多值依赖于由U中不属于X和Y的其他属性组成的集合Z。

  • 直观解释:

    当你知道X的值可以决定Y的多个值时,同样也可以理解为其他非X和Y的属性(集合Z)的值也可以由X决定(尽管它们之间可能没有直接的业务逻辑联系)。

    例子:

    假设我们有一个关系模式R(A, B, C),其中A是员工ID,B是员工可以负责的多个项目ID,C是项目类型(比如“研发”、“市场”等)。

    • 如果A→→B(一个员工可以负责多个项目),那么根据对称性,A也必然多值依赖于C(即,给定一个员工ID,他/她负责的项目中可能包含多种项目类型)。但这里要注意的是,对称性并不意味着A直接决定C,只是说在给定的A的值下,C有多个可能的值。

  • 传递性:如果X→→Y,Y→→Z,则X→→Z-Y。

  • 直观解释:

    如果X的值可以决定Y的多个值,而Y的值又可以决定Z的多个值(其中Z不包含Y),那么我们可以推断出X的值也可以直接决定Z中除了Y之外的那些值的多个可能值。

    例子:

    回到上面的例子,假设除了A、B、C之外,还有一个属性D表示项目的预算范围(如“低”、“中”、“高”)。

    • 如果A→→B(员工与项目)和B→→D(项目与预算范围),那么根据传递性,A也必然多值依赖于D-B(即,给定一个员工ID,他/她负责的项目中有多种预算范围,但不需要具体知道是哪些项目)。

  • 函数依赖可以看成是多值依赖的特殊情况如果X→Y(即X函数决定Y),那么X→→Y也必然成立。因此,可以将函数依赖看作是多值依赖的特殊情况。

  • 直观解释:

    函数依赖描述的是一对一或一对零的关系,即X的值唯一确定Y的值。而多值依赖描述的是一对多的关系。由于一对一或一对零也可以看作是一种特殊的一对多(其中“多”的个数为1),因此函数依赖可以看作是多值依赖的一种特殊情况。

    例子:

    假设在关系模式R(A, B)中,A是员工ID,B是员工的唯一经理ID。

    • 在这个例子中,A→B(员工与经理之间存在函数依赖关系,因为每个员工只有一个经理)。由于函数依赖描述的是一对一或一对零的关系,它也可以被看作是多值依赖A→→B的一个特例,其中“多”的个数为1。

4NF

4NF就是限制关系模式的属性之间不允许有非平凡但非函数依赖的多值依赖。

在3NF中,我们解决了非主属性对候选键的部分依赖和传递依赖问题,但仍然存在一些可能导致数据冗余和更新异常的情况。例如,当一个关系模式中存在非平凡且非候选键的多值依赖时,就可能出现这种情况。4NF通过限制这种多值依赖来进一步减少数据冗余和更新异常的可能性。

要满足4NF,通常需要对关系模式进行分解。具体来说,如果关系模式中存在非平凡且非候选键的多值依赖X→→Y,则需要将关系模式分解为两个或多个新的关系模式,使得每个新的关系模式都满足4NF的条件。

具体步骤如下:

  • 选择多值依赖:选择一个违反4NF的多值依赖X→→Y。

  • 创建新关系:基于X和Y创建一个新的关系模式。

  • 处理剩余属性:将原始关系模式中不属于X或Y的其他属性分配到新的关系模式或保留在原始关系模式中(如果它们与X或Y有其他依赖关系)。

  • 重复:对新的关系模式重复上述步骤,直到所有关系模式都满足4NF。

规范化小结

规范化的基本思想是逐步消除数据依赖中不合适的部分,使模式中的个关系达到某某种程度的“分离”,即“一事一地”的模式设计原则。规范化实质上就是概念的单一化。

关系模式的规范化过程是通过对关系模式的分解来实现的,即把低一级的关系模式分解为若干个高一级的关系模式。

Armstrong公理系统

Armstrong公理系统的主要规则包括:

  1. 自反律(Reflexivity):如果Y是X的子集(Y ⊆ X),那么X到Y的函数依赖(X → Y)在关系R上总是成立的。这是一种平凡的函数依赖。

  2. 增广律(Augmentation):如果X → Y在关系R上成立,并且Z是关系R的属性集U的任意子集,那么XZ → YZ也在关系R上成立。

  3. 传递律(Transitivity):如果X → Y和Y → Z在关系R上成立,那么X → Z也在关系R上成立。

基于上述三条基本规则,还可以推导出其他的推理规则,如:

  • 合并规则(Union):如果X → Y和X → Z在关系R上同时成立,那么X → YZ也在关系R上成立。

  • 分解规则(Decomposition):如果X → W在关系R上成立,并且Z是W的子集,那么X → Z也在关系R上成立。

  • 伪传递规则(Pseudo-transitivity):如果X → Y在关系R上成立,并且存在另一个函数依赖WY → Z,那么XW → Z也在关系R上成立。

Armstrong公理系统的有效性指的是,由关系R出发根据Armstrong公理系统推导出来的每一个函数依赖一定是R所逻辑蕴含的函数依赖。同时,Armstrong公理系统的完备性指的是,对于R所逻辑蕴含的每一函数依赖,必定可以由R出发根据Armstrong公理系统推导出来。

闭包与最小依赖集

闭包

在数据库设计中,闭包通常指的是属性集X关于函数依赖集F的闭包。这里的闭包描述的是给定属性集X,根据现有的函数依赖集F,能推出哪些属性。这是一个逻辑推导的过程,用于确定数据库表中哪些属性是相互依赖的。

最小依赖集

最小依赖集(Minimal Dependency Set)在计算机科学领域,特别是在数据库设计中,是一个非常重要的概念。它指的是在给定的一组依赖关系中,找到一个最小的子集,使得在这个子集中不存在多余或冗余的依赖关系。这里的“最小”和“冗余”通常基于某种特定的定义或标准,如Armstrong公理系统。

在数据库设计中,最小依赖集的概念与函数依赖(Functional Dependency)密切相关。函数依赖描述的是数据库表中属性之间的依赖关系,即一个属性的值可以由另一个或一组属性的值唯一确定。而最小依赖集则是在给定的函数依赖集中找出最小(无冗余)的依赖关系集合。

联系

在数据库设计中,闭包和最小依赖集的概念是相互关联的。具体来说,当我们讨论一个关系模式R(U,F)时,其中U是属性的全集,F是函数依赖集。为了优化这个关系模式,我们可能需要找到F的最小依赖集,以减少冗余的依赖关系。而在计算最小依赖集的过程中,我们可能会使用到闭包的概念。例如,在算法中,我们可能需要计算某个属性集的闭包,以判断某个函数依赖是否可以从其他函数依赖中推导出来。

菜菜,捞捞~