通俗理解:平凡/非平凡/完全/部分函数依赖 & 范式

函数依赖

函数依赖可以理解为

        通过一个属性可以唯一确定另一个属性的值

举例:

  1. ISBN -> 书名,作者,出版社

    意思是:如果你知道一本书的 ISBN,就能唯一确定这本书的 书名作者出版社。因为 ISBN 是每本书独一无二的。
  2. 书名 -> 作者

    假设图书馆只存一本书的一个版本,那么知道一本书的 书名,你也就知道了这本书的 作者。例如:
    • "西游记" -> "吴承恩"
    • "红楼梦" -> "曹雪芹"
  3. 书名 -> 出版社

    如果每本书只有一个版本(只有一个出版社出版),那么知道 书名 就可以确定 出版社。但如果一本书有多个版本(不同出版社出版),这个依赖就不成立了。
  4. 知道身份证号(类似主键),就知道一个人的所有信息。
  5. 知道车牌号,就能找到车辆的注册信息。

平凡函数依赖

定义:如果一个函数依赖的右边属性是左边属性的子集,称为平凡函数依赖。

换句话说,你知道的本来就包括右边的信息,这没什么意义

在图书馆的图书表中(属性:ISBN, 书名, 作者, 出版社):

  1. (ISBN, 书名) → 书名

    • 这是平凡函数依赖,因为右边的 书名 已经包含在左边的属性 (ISBN, 书名) 中。
    • 换句话说:既然你已经知道 ISBN 和书名了,书名当然是确定的,这没什么新信息。
  2. (书名, 作者) → 作者

    • 这也是平凡函数依赖,因为右边的 作者 是左边的一个属性。

非平凡函数依赖

定义:如果一个函数依赖的右边属性不是左边属性的子集,称为非平凡函数依赖。

换句话说,右边的属性依赖于左边的信息,是新得出的结论

  1. ISBN → 书名

    • 这是非平凡函数依赖,因为 书名 不属于左边的属性(ISBN)。
    • 意义在于:通过 ISBN,你可以唯一确定书名。
  2. 书名 → 作者

    • 如果每本书只有一个作者,这就是非平凡函数依赖。
    • 意义在于:通过书名,可以确定作者。

完全函数依赖

定义:在一个复合键(由多个属性组成的键)中,如果右边的属性完全依赖于整个键,而不是键的一部分,这种依赖关系称为完全函数依赖。

假设图书馆的表有以下属性:

  • (ISBN, 分馆) → 馆藏数量
    • ISBN:图书的国际标准书号。
    • 分馆:图书馆的分馆名称。
    • 馆藏数量:某分馆的某本书的库存量。

这里 (ISBN, 分馆) 是复合键。

  1. 完全函数依赖:

    (ISBN, 分馆) → 馆藏数量

        要确定某本书的馆藏数量,你需要同时知道 ISBN分馆,缺一不可。例如:ISBN =         "12345",分馆 = "A馆",对应馆藏数量是 10;如果只知道 ISBN,你无法确定分馆的馆藏数量。

        这就是完全函数依赖,因为馆藏数量依赖于整个复合键 (ISBN, 分馆),而不是键的一部分。


部分函数依赖

定义:在一个复合键中,如果右边的属性依赖于复合键的一部分(而不是整个键),这种依赖关系称为部分函数依赖。

假设同样的图书馆表中:

  1. 部分函数依赖

    ISBN → 书名

        知道 ISBN 就能确定书名,而与分馆无关。

        例如:ISBN = "12345",书名是《红楼梦》。书名只依赖 ISBN,而不依赖复合键的另一部分 分馆

范式

假设一个学生选课系统,有以下初始表:

学号学生姓名学院课程名任课老师教室
1001张三计算机学院数据库王老师A101
1002李四数学学院高数李老师B202
1001张三计算机学院高数李老师B202

第一范式(1NF)——消除重复数据,所有列的值必须是原子值

  • 要求:表中的每一列只能存储单一值,不能是列表或集合。也就是说,数据必须是“原子化”的。

不符合1NF的情况:

学号学生姓名学院课程名任课老师教室
1001张三计算机学院数据库, 高数王老师, 李老师A101, B202

这里的“课程名”、“任课老师”、“教室”列中存储了多个值,不是原子化的。

1NF 转换:

将每个课程分成单独的记录:

学号学生姓名学院课程名任课老师教室
1001张三计算机学院数据库王老师A101
1002李四数学学院高数李老师B202
1001张三计算机学院高数李老师B202

1NF 解决了数据的非原子化问题。


第二范式(2NF)——消除部分依赖

  • 要求:表必须满足 1NF,且非主属性完全依赖于主键,不能存在部分函数依赖。

在上面的例子中主键是 (学号, 课程名)(因为“学号+课程名”唯一标识一条记录),我们发现:

  1. 学生姓名和学院只依赖于“学号”,而不依赖于复合主键的“课程名”部分(部分依赖)。
  2. 这会导致冗余:如果同一个学生选了多门课,学生的姓名和学院信息会重复存储。

2NF 转换:

拆分表,消除部分依赖:

  1. 学生信息表(只存储与“学号”相关的信息):

    学号学生姓名学院
    1001张三计算机学院
    1002李四数学学院
  2. 选课信息表(只存储与“学号+课程名”相关的信息):

    学号课程名任课老师教室
    1001数据库王老师A101
    1001高数李老师B202
    1002高数李老师B202

2NF 解决了部分函数依赖,减少了数据冗余。


第三范式(3NF)——消除传递依赖

  • 要求:表必须满足 2NF,且非主属性不能传递依赖于主键

在选课信息表中:

  1. “教室”依赖于“课程名”(课程名决定教室)。
  2. “课程名”又依赖于主键“(学号, 课程名)”。
  3. 因此,“教室”是通过“课程名”传递依赖于主键的,这会导致冗余:同一个课程的教室信息可能被重复存储。

3NF 转换:

进一步拆分表,消除传递依赖:

  1. 学生信息表:

    学号学生姓名学院
    1001张三计算机学院
    1002李四数学学院
  2. 选课信息表:

    学号课程名
    1001数据库
    1001高数
    1002高数
  3. 课程信息表:

    课程名任课老师教室
    数据库王老师A101
    高数李老师B202

3NF 解决了传递依赖问题,进一步减少了数据冗余。


BCNF(Boyce-Codd Normal Form)——更严格的第三范式

  • 要求:在每个函数依赖中,左边的属性必须是候选键

特殊情况:

3NF 中如果存在非主属性决定主属性的情况,就不满足 BCNF。

例如:如果选课表变成这样:

学号课程名任课老师
1001数据库王老师
1001高数李老师
1002高数李老师

这里存在:

  • 任课老师 → 课程名(任课老师决定课程名)。
  • 但是“任课老师”不是候选键,违背了 BCNF。

BCNF 转换:

将表拆分为:

  1. 学生选课表:

    学号课程名
    1001数据库
    1001高数
    1002高数
  2. 任课老师表:

    课程名任课老师
    数据库王老师
    高数李老师

总结

范式核心问题解决方法
1NF数据非原子化(多值或集合)拆分成单一值的记录
2NF存在部分函数依赖拆分表,消除部分依赖
3NF存在传递依赖拆分表,消除传递依赖
BCNF非候选键的属性决定其他属性更严格地规范主键和依赖关系
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值