系统分析师笔记(六)-- 数据库:主属性、候选码、超码、E-R图

用“元素”和“集合”的视角来区分,这是理解数据库范式和关系理论的逻辑。

理解复盘与微调:

  1. 主属性 = 元素(原子属性) ✅

    • 正确。主属性是单个的属性(比如 A、B)。注意,它必须是包含在任意一个候选码里的属性。
  2. 候选码 = 只由主属性构成的最小集合 ✅(逻辑上绝对正确)

    • 这里的“最小”有两层含义:一是属性个数最少,二是完全函数依赖(不能有冗余属性)。
    • 补充一个细节:既然候选码是由主属性构成的,那非主属性能不能进候选码?不能。因为如果非主属性在候选码里,它就能决定其他属性,那它本身就变成主属性了(自相矛盾)。所以你的“只由主属性构成”这句话,逻辑闭环非常完美。
  3. 超码 = 包含候选码的更大的集合 ✅

    • 正确。超码就是“候选码 + 任意其他属性(可以是主属性,也可以是非主属性)”。
    • 补充一个细节:超码是不要求最小的。所以超码可能很“臃肿”,包含了一堆无关的属性。

一个形象的比喻(乐高积木理论)

  • 主属性 = 乐高积木块(单个零件)。
  • 候选码 = 能够拼成一辆完整小汽车(决定所有属性)的最少积木组合(比如:底盘+轮子)。拆掉任何一个,车就拼不成。
  • 超码 = 在“底盘+轮子”的基础上,你再随便加几块多余的积木(比如加个车顶,或者加个尾翼),它仍然是一辆完整的车(依然能决定所有属性),但积木数量变多了,不是最小的了。

唯一需要小心的“逻辑陷阱”

虽然“候选码只由主属性构成”是对的,但千万不要反过来理解为“只要由主属性构成的集合就是候选码”。
比如,主属性有 A 和 B,超码 {A, B} 是由主属性构成的,但它不是候选码(因为它太大了,单独 A 或 B 就能决定所有属性)。

修正后的完整表述:

  • 主属性是构成候选码的“零件”。
  • 候选码是由主属性构成的、能唯一标识元组、且不能再精简的最小集合。
  • 超码是包含至少一个候选码的集合(可能包含非主属性的冗余零件)。

多值依赖(有冗余,要拆表)

image

关键:两个一对多,两个“多”独立

  • 怎么快速识别多值依赖?
    只要看到:A决定B(一对多),A决定C(一对多),且B和C没有依赖关系,B和C的数据呈现出完全交叉组合(笛卡尔积)。
    立刻判定:存在多值依赖 A →→ B 和 A →→ C。

  • 多值依赖带来的问题(考点)

    • 极度冗余:“数据库”三个字重复了4次,张老师重复了2次,书名也重复了2次。
    • 操作异常:
      • 如果我们要新增一位“李老师”教“数据库”,如果不给他指定参考书,我们就无法插入这条记录(插入异常)。
      • 如果我们要删除《SQL必知必会》这本书,就会连带把王老师教数据库的信息也删掉(删除异常)。

---------------------> 多值依赖 不存在 函数依赖<------------------------

  • 如何消除多值依赖?(第四范式 4NF)
    • 要消除多值依赖,必须把这张表拆开,拆成两张表:
      • 表1(课程-教师):课程,教师
      • 表2(课程-参考书):课程,参考书
    • 这样,教师和参考书各自独立,互不影响,彻底解决了冗余和异常。

这也是软考中常考的第四范式(4NF)的核心定义:在满足3NF的基础上,消除非平凡且 非函数依赖 的多值依赖。

笛卡尔积

一、 生活里的“笛卡尔积”:组合搭配

假设你早上出门挑衣服:

  • 上衣(集合A):有2件 ——
  • 裤子(集合B):有3条 ——

如果要求你必须穿一件上衣搭配一条裤子,请问有多少种穿法?
答案是:2 × 3 = 6 种。

这所有可能的组合,就是“上衣”和“裤子”的笛卡尔积。


二、 数学上的正式定义

在数学中,两个集合 (A) 和 (B) 的笛卡尔积,记作 (A \times B)。
它的定义是:用集合A里的每一个元素,去匹配集合B里的每一个元素,组成的所有“有序对”的集合。

  • 数学公式:(A \times B = {(a, b) \mid a \in A, b \in B})
  • 规律:结果的总个数 = 集合A的元素个数 × 集合B的元素个数。

三、 数据库里的“笛卡尔积”(关系代数)(元素 <--> 行)

在数据库里,“集合”变成了“表(关系)”,“元素”变成了“行(元组)”。笛卡尔积的规则是:

  • 列数相加:结果表的列数 = 表A的列数 + 表B的列数。
  • 行数相乘:结果表的行数 = 表A的行数 × 表B的行数。
  • 每一行进行“拼接”:表A的每一行,都要和表B的每一行拼成一条完整的新行。

举个数据库的例子:
有两张表:
表A(学生表)

学号 姓名
1 张三
2 李四

表B(课程表)

课程号 课程名
C1 语文
C2 数学

表A × 表B(笛卡尔积结果):

学号 姓名 课程号 课程名
1 张三 C1 语文
1 张三 C2 数学
2 李四 C1 语文
2 李四 C2 数学

你会发现,2个学生 × 2门课 = 4条记录(行数相乘),列数也是4列(2+2)。
这就是数据库里的笛卡尔积。


四、 “完全独立的笛卡尔积”

现在再看之前“课程-教师-参考书”的例子,就好懂了:

  • 对于“数据库”这门课(固定值):
  • 教师有2个:
  • 参考书有2本:
  • 因为“教师”和“参考书”完全独立,所以它们就像上衣和裤子一样,必须进行“全排列组合”(2×2=4种),就构成了“完全独立的笛卡尔积”。

五、 笛卡尔积在考试和实际中的意义

  1. 它是“连接(Join)”的基础:在数据库里,两张表想要关联起来(比如查询“选了语文课的学生”),第一步在底层就是先做笛卡尔积(把所有学生和所有课程组合起来),然后再通过条件(WHERE 学号=选课表.学号)去过滤掉无意义的组合。
  2. 它是一个“超级炸弹”:在没有过滤条件的情况下,如果你对两张几千行、几百行的表做笛卡尔积,结果可能变成几亿行,直接把数据库内存撑爆。所以我们在写 SQL 时,一定要避免产生无意义的笛卡尔积(即忘记写多表连接的条件)。
  3. 多值依赖的灾难:之前说的多值依赖,本质上就是由于表里出现了“完全独立的笛卡尔积”(比如教师和书),导致了极度严重的数据冗余。解决的办法就是“拆表”,把“课程-教师”和“课程-参考书”拆开,这样每个表里就没有笛卡尔积了。

范式:概念及判断

image

范式,是用来度量关系函数的好坏的

函数依赖 X → A 的情况 最高只能达到 分析
存在 非主属性 部分依赖于 组合码 1NF X 是组合码的真子集
存在 非主属性 传递依赖于 非超码 2NF X 是非超码,A 是非主属性
存在 主属性 依赖于 非超码 3NF X 是非超码,A 是主属性
所有 X(左边) 都是 超码 BCNF 完美,无任何非超码决定属性
posted on 2026-09-27 12:24  中年二班  阅读(7)  评论(0)    收藏  举报