DBMS - 规范化
函数依赖
功能依赖 (FD) 是关系中两个属性之间的一组约束。 函数依赖表示如果两个元组的属性 A1、A2、...、An 的值相同,那么这两个元组的属性 B1、B2、...、Bn 的值必须相同。
函数依赖由箭头符号 (→) 表示,即 X→Y,其中 X 在功能上确定 Y。左侧属性确定右侧属性的值。
阿姆斯特朗公理
如果 F 是一组函数依赖,那么 F 的闭包,表示为 F+,是由 F 逻辑暗示的所有函数依赖的集合。阿姆斯特朗公理是一组规则,即 重复应用时,会生成函数依赖的闭包。
自反规则 − 如果 alpha 是一组属性并且 beta is_subset_of alpha,则 alpha 持有 beta。
增强规则 − 如果 a → b 成立并且 y 是属性集,那么 ay → by 也成立。 即在依赖项中添加属性,不会改变基本依赖项。
传递性规则 − 与代数中的传递规则相同,如果 a → b 成立且 b → c 成立,则 a → c 也成立。 a → b 被称为决定 b 的函数。
琐碎的函数依赖
平凡 − 如果函数依赖 (FD) X → Y 成立,其中 Y 是 X 的子集,则它被称为平凡函数依赖。 平凡的函数依赖始终成立。
非平凡 − 如果函数依赖 (FD) X → Y 成立,其中 Y 不是 X 的子集,那么它被称为非平凡函数依赖。
完全不平凡 − 如果函数依赖 (FD) X → Y 成立,其中 x 与 Y = Φ 相交,则称它是完全非平凡的函数依赖。
标准化
如果数据库设计不完美,它可能包含异常,这对任何数据库管理员来说都是一个噩梦。 管理有异常的数据库几乎是不可能的。
更新异常 − 如果数据项分散并且没有正确地相互链接,那么它可能会导致奇怪的情况。 例如,当我们尝试更新一个其副本分散在多个地方的数据项时,一些实例会正确更新,而其他一些实例则保留旧值。 此类实例使数据库处于不一致的状态。
删除异常 − 我们试图删除一条记录,但由于不知情,部分记录未删除,数据也保存在其他地方。
插入异常 − 我们试图在根本不存在的记录中插入数据。
规范化是一种消除所有这些异常并使数据库处于一致状态的方法。
第一范式
第一范式是在关系(表)本身的定义中定义的。 此规则定义关系中的所有属性都必须具有原子域。 原子域中的值是不可分割的单位。
我们重新排列关系(表格)如下,将其转换为第一范式。
每个属性只能包含来自其预定义域的单个值。
第二范式
在学习第二范式之前,我们需要了解以下内容 −
主要属性 − 作为候选键的一部分的属性称为主属性。
非主属性 − 不属于主键的属性称为非主属性。
如果我们遵循第二范式,那么每个非主属性都应该在功能上完全依赖于主键属性。 也就是说,如果 X → A 成立,那么 X 的任何真子集 Y 都不应该存在,而 Y → A 也成立。
我们在 Student_Project 关系中看到,主键属性是 Stu_ID 和 Proj_ID。 根据规则,非键属性,即 Stu_Name 和 Proj_Name 必须依赖于两者,而不是单独依赖于任何主键属性。 但是我们发现Stu_Name可以被Stu_ID识别,Proj_Name可以被Proj_ID独立识别。 这称为部分依赖,在第二范式中是不允许的。
如上图所示,我们将关系一分为二。 所以不存在部分依赖。
第三范式
对于处于第三范式的关系,它必须处于第二范式并且以下必须满足 −
- 没有非主属性传递依赖于主键属性。
- 对于任何非平凡的函数依赖,X → A,然后要么 −
- X 是一个超级键,或者,
- A 是主要属性。
我们发现在上面的Student_detail关系中,Stu_ID是唯一的主键属性。 我们发现 City 可以通过 Stu_ID 以及 Zip 本身来识别。 Zip 既不是超级键,City 也不是主要属性。 另外,Stu_ID → Zip → City,所以存在传递依赖。
为了把这个关系带入第三范式,我们把这个关系分成两个关系如下 −
Boyce-Codd 范式
Boyce-Codd 范式 (BCNF) 是严格意义上的第三范式的扩展。 BCNF 指出 −
- 对于任何非平凡的函数依赖,X → A, X 必须是一个超键。
在上图中,Stu_ID 是 Student_Detail 关系中的超键,Zip 是 ZipCodes 关系中的超键。 所以,
Stu_ID → Stu_Name, Zip
和
Zip → City
这证实了这两个关系都在 BCNF 中。