2.3 关系的码和关系的完整性
这一节回答两个问题:靠什么认出表里的一行,表与表之间靠什么连起来。

重 点这一块看的时候抓三点
候选码要同时满足唯一性和最小性,第 30 页有一个可以动手试的判断器。主码是从候选码里挑出来日常用的那一个,每个关系只有一个。外码是别的表的主码放到我这张表里,表和表就靠它连起来。下一节的三类完整性,前两类正好盯着主码和外码。
想一想
在一张没有学号的学生表里,你打算靠什么认人?
这一节回答两个问题:靠什么认出表里的一行,表与表之间靠什么连起来。

候选码要同时满足唯一性和最小性,第 30 页有一个可以动手试的判断器。主码是从候选码里挑出来日常用的那一个,每个关系只有一个。外码是别的表的主码放到我这张表里,表和表就靠它连起来。下一节的三类完整性,前两类正好盯着主码和外码。
在一张没有学号的学生表里,你打算靠什么认人?
候选码是能唯一区分元组、且去掉任何一个属性就不再唯一的属性集,唯一性和最小性缺一不可。

唯一性说任何两行在这组属性上的值都不同。最小性说这组属性一个都不能少,少一个就不再唯一。课件的三个例子:课程号一个属性就够了。授课关系要教师号加课程号,一位教师可以教多门课,一门课也可以由多位教师教。选课关系的学号加课程号,去掉哪一个都会重复。
一把能开门的钥匙是唯一性。钥匙串上再多挂一把没用的,门照样能开,但这串钥匙就不是最小的了。
“姓名加性别”能不能做学生表的候选码?
学号是候选码,身份证号也是候选码,学号加姓名虽然唯一但不最小,叫超码。

先看唯一,再看最小,两条都满足的是候选码,只满足唯一的是超码,连唯一都不满足的就不是码。例子 B 的三列合起来才唯一,去掉任何一列都会出现重复,所以三列一起是候选码,它只有这一个候选码。
| studentId | idCard | name | phone |
|---|---|---|---|
| S001 | 110101 | 张三 | 138001 |
| S002 | 110102 | 李四 | 138002 |
| S003 | 110103 | 张三 | 138003 |
| S004 | 110104 | 王五 | 138002 |
身份证号加学号是候选码还是超码?
候选码可能有几个,主码只能有一个,从候选码里挑一个日常使用,其余的用 UNIQUE 保留。

课件下半页的四条原则:稳定,不随业务变化,学号比手机号稳。短小,单列优先于多列,存储和索引都省。不含空值,空值认不出任何一行。便于被别的表引用,常被外键引用的列要好用。例子 A 挑学号不挑身份证号,学号短而且不涉及隐私,身份证号加 UNIQUE 约束保留唯一性。例子 B 只有一个候选码,它就是主码。规则一句话:每个关系有且只有一个主码。
候选码可以有多个,主码只能从中选一个。其余候选码的唯一性可以用 UNIQUE 约束保留,但它们不叫主码。
手机号为什么不适合做主码?
出现在候选码里的属性是主属性,任何一个候选码都不沾的属性是非主属性。

教材原文说主属性是包含在主码中的属性,课件下半页说是出现在任一候选码中的属性。只有一个候选码时两种说法一样。有多个候选码时按候选码算更常用,例子 A 里身份证号没被选为主码,但它是候选码,所以算主属性。例子 B 三个属性都是主属性,grade 是非主属性。这个区分第 12 章判断部分依赖和传递依赖时会用到。
教师关系里,姓名是主属性还是非主属性?
外码是在本关系里不是主码、却是另一个关系主码的属性,本关系叫参照关系,被指向的叫被参照关系。

属性 X 在 R1 里是主码,在 R2 里是外码,箭头从 R2 指向 R1。底部那句话很重要:两边必须定义在同一个域上,学号在学生表和选课表里必须是同一种类型。选课(学号,课程号,成绩) 里学号是外码,参照学生表,课程号也是外码,参照课程表。
快递单上的收件人手机号:在你的通讯录里它是认人的主码,在快递单上它是指向你的外码。快递单不需要抄一遍你的全部信息,有这个号码就能找到你。
授课(教师号,课程号) 里有几个外码?
学生表里的身份证号引用公民表的主码,所以它是学生表的外码,没有外码约束就会出现查无此人的记录。

身份证号在公民表里是主码,在学生表里是外码而不是主码,学生表的主码是学号。外码约束的作用是拒绝 999999 这种公民表里根本没有的值,课件的原话是“数据就乱了”。这一条到第五节就叫参照完整性。
宿舍住宿登记表上写的房间号必须是楼里真有的房间,写一个不存在的 999 室,登记就该被退回。楼里的房间表是被参照关系,登记表是参照关系。
学生表里的“姓名”也出现在公民表里,它是外码吗?