
带学生复习数据库第2章时,我经常发现一个现象:不少同学上课听懂了概念,一到单元测验就翻车。尤其是关系模型这一章,它不像后面SQL章节那样可以直接上手写代码,全是些“定义理解”“性质辨析”“表达式书写”的题型,知识点细碎,考法又灵活,光靠死记硬背很难得分。这篇文章我按平时给学生做复习课的思路,把关系模型这一章的核心考点、典型题目拆解方式、以及我自己批改作业时反复遇到的问题,完整捋一遍,希望能帮你把这一章彻底吃透。关系模型不是什么高深理论,它是现在几乎所有主流数据库——MySQL、Oracle、达梦、人大金仓,底层都在用的数据组织方式。你后面学SQL、学索引、学事务,回过来头看,全都建立在这一章的几条基本规则上。所以单元测验不是终点,它是一个承上启下的锚点,值得多花点心思。1. 关系模型到底在考什么先理清测验的宏观方向1.1 从“背概念”到“用概念”关系模型的考察层次很多同学复习这一章时,习惯把书上的定义逐条背诵:关系、元组、属性、域、候选键、主键、外键……背得很熟,但一做题就懵。原因在于单元测验考察的不是“你能背出定义”,而是“你能不能拿定义去判断一个实际问题”。我举个例子,书上说“关系是笛卡尔积的子集”,这句话背下来只要10秒,但题目如果问你“为什么关系不允许出现完全相同的两行”,你还是得回到笛卡尔积和集合的定义去理解——集合中的元素不允许重复,关系是集合,所以关系里就不能有两行完全一样的数据。所以复习这一章,要从“背定义”切换到“用定义”。每条定义你都问自己三个问题:它规定了什么?它排除了什么?它为什么这样规定?把这三个问题想通了,选择题和判断题基本不会丢分。比如“关系的列是无序的”这条性质,它规定的是关系模型层面逻辑结构,和物理存储顺序无关;它排除的是“通过列的位置来引用数据”这种用法;它这样规定是为了让逻辑模型独立于物理实现,后续SQL里SELECT语句按列名取值、不按下标取值,根源就在这里。1.2 一个单元测验的典型知识边界根据我接触过的多套数据库教材和试卷,这一章单元测验的出题范围一般集中在四个模块:关系模型的基本概念、关系的完整性约束、关系代数运算、关系模型与常见数据库系统的对应关系。基本概念模块考的是关系、元组、属性、域、关系模式、关系数据库等术语的含义,以及关系的六条性质。完整性约束模块考实体完整性、参照完整性、用户自定义完整性的适用场景,外键的取值规则。关系代数模块考选择、投影、连接、除等运算的语义和表达式书写,有时还会要求判断两个关系代数表达式是否等价。最后一个模块通常以选择题或简答题形式出现,比如“简述关系模型的优点”或者“为什么关系模型能成为主流数据模型”。这四个模块里,前两个是基础,后两个是重头戏。关系代数部分往往占分最多,因为它直接考验逻辑能力,也是后面学SQL时写查询语句的思维原型。后面我会重点讲关系代数的做题套路。2. 核心知识点拆解拿到题先想这几个底层规则2.1 关系的六条性质判断“是不是关系”的尺子我在批改作业时发现,很多同学对关系性质的理解停留在“知道有六条”这个层面,一旦题目换个方式问就答不上来。这里我把六条性质逐条讲透,并说明每条性质对应着什么样的考查方式。第一条,关系中的每一个分量必须是不可分的数据项。这条性质也叫关系的原子性,是关系模型最基本的前提。它排除了“表中套表”的情况。考题常见的问法是给你一个表格,里面有“籍贯”列,值写成“广东省广州市”,问这个表能否直接作为关系中的关系。答案是不能,因为籍贯被分成了省和市两个可再分的数据项,必须先拆成“籍贯省份”和“籍贯城市”两列,或者统一精度。第二条,关系中的每一列必须具有相同的数据类型,即同质性。同一列上所有取值来自同一个域,类型必须一致。这听起来简单,但实务中经常有人在设计表时把“年龄”列存成各种格式,有的是字符串、有的是整数,这在关系模型里是不允许的。第三条,不同的列可出自同一个域。这条性质是让很多人困惑的地方。域是值的集合,比如“性别”和“婚姻状况”这两个属性,它们的取值域都可以是“男、女”,但它们是不同的列。考判断题时,如果题干说“不同的列不能来自同一个域”,那就是错的。第四条,关系中行的顺序可以任意交换。注意,这里说的是关系模型层面的逻辑特性,不是物理存储。实际数据库里数据在磁盘上当然是有顺序的,但关系模型不保证也不依赖这个顺序。SQL查询时如果不加ORDER BY,结果顺序是不确定的,这是同一个道理。第五条,关系中列的顺序可以任意交换。和行序同理,列的顺序也不构成信息。所以你写关系模式时,Student(学号,姓名,性别)和Student(姓名,学号,性别)描述的是同一个关系模式。第六条,关系中不允许出现两个完全相同的元组。这个是集合论决定的,关系是集合,集合没有重复元素。这条性质在实体完整性中还会体现:主键的存在保证了元组可唯一区分。这里我给大家一个记忆抓手:把关系想成一张“语义明确、没有冗余重复行、行列顺序都不重要、单元格不能再拆的二维表”。凡是违背这六条中任何一条的二维表,都不能直接称为关系。2.2 候选键、主键、外键键相关的几类高频考法键是关系模型中最重要的概念之一,也是测验喜欢出题的地方。先捋一下几个概念的关系:超键是能唯一标识元组的属性集合,候选键是最小的超键,主键是从候选键里挑出来的一个,外键是引用其他关系主键的属性。考法一:给一个关系模式,让你找出所有候选键。这种题需要你根据函数依赖来分析。比如有关系R(A,B,C,D),函数依赖是A→B,B→C,问你候选键有哪些。做题时先找哪些属性不在任何函数依赖的右边,A不在,所以A一定是候选键的一部分。由A能推出B,由B能推出C,但A推不出D,所以A和D组合成候选键,候选键是(A,D)。这类题不能靠猜,要系统地运用闭包计算。考法二:辨析超键、候选键、主键。常见的错误是认为主键只有一个属性。主键可以由多个属性组合而成,这叫复合主键。比如选课关系选课(学号,课程号,成绩),主键就是(学号,课程号)这个组合。考法三:外键的取值规则。外键要么取被引用关系中实际存在的主键值,要么取空值。注意,这个“空值”是有前提的——如果外键是所在关系主键的一部分,那么它不能取空值,否则违反实体完整性。这个细节几乎是必考点,后面讲完整性时会再展开。2.3 三类完整性约束为什么参照完整性最容易丢分关系的三类完整性约束,分别是实体完整性、参照完整性和用户自定义完整性。实体完整性的内容是:主键的属性值不能取空值。理解时要扣住“主键是用来唯一标识元组”的这个功能。如果主键为空,你就无法区分这一行数据到底是谁,唯一标识的意义就没了。测验里经常出这样的判断题:某个关系的主键是(学号,课程号),现在插入一条数据,学号和课程号都不为空,但成绩为空,问是否违反实体完整性。答案是不违反,因为实体完整性只约束主键属性,成绩不是主键属性,成绩为空最多是违反用户自定义完整性设置。参照完整性规定的是:外键的值要么是被参照关系的主键中实际存在的值,要么为空值。这里我见过最多的错法是判断参照完整性时只看“存不存在”,忽略“空值可不可取”。我再强调一遍:外键为空值的前提是,这个外键不是它所在关系主键的一部分。如果外键本身就是主键的组成部分,那就同时受实体完整性约束,不能为空。用户自定义完整性是针对某个具体应用场景额外定义的约束,比如“年龄大于0”“成绩在0到100之间”“性别只能取男或女”。这类约束在SQL里用CHECK约束实现,测验中通常考你“某个规则属于哪一类完整性”。判断技巧是:凡是和主键相关的,选实体;凡是和外键相关的,选参照;凡是普通业务规则,选用户自定义。3. 关系代数运算的实操套路从读题到写表达式3.1 五类基本运算怎么区分关系代数是这一章的实际操作部分。书上会讲八个运算,但核心的基本运算是五个:并、差、笛卡尔积、选择、投影。另外三个——交、连接、除,可以由基本运算推导出来。并运算考察的是两个关系合并。写表达式时有个前提条件必须满足:两个关系要并兼容,具体说是属性数量相同,且对应属性的域相同。很多同学在这里犯迷糊:两个关系属性一样,值也差不多,能不能并?答案是不能,必须属性个数相同,还得对应属性的类型一致。差运算跟数学里的集合差完全一致,R - S表示在R中但不在S中的元组。注意顺序,S - R和R - S结果不同。笛卡尔积运算是把两个关系所有行组合在一起。如果R有m行、n个属性,S有p行、q个属性,那么R×S有m×p行、nq个属性。笛卡尔积本身意义不大,但它和选择、投影组合起来就能表达连接运算,所以它是最底层的运算。选择运算是从行角度筛选,写做σ条件(R),选出满足条件的元组。投影运算是从列角度裁切,写做π属性列表(R),去掉不需要的列。选择的条件用比较运算符、逻辑运算符连接,投影的列用逗号分隔。这两个运算的区分是高频考点:选择是挑行,投影是选列。实在搞混了就记一句话:选择在“行”上动手,投影在“列”上动手。3.2 连接运算与选择、投影的组合连接运算在测验里一般有三种出现方式:等值连接、自然连接、以及连接和选择投影的组合使用。等值连接是从笛卡尔积中选取指定列值相等的元组。写法是R⋈S,再加条件。比如R⋈(AB)S,就是R和S做笛卡尔积后,只保留A列等于B列的那些行。自然连接是特殊的等值连接,它比较的是两个关系中所有同名属性,并在结果中去掉重复的同名列。这是最容易出细节题的地方:自然连接结果中,重复属性只保留一列。我见过不少同学考试时把自然连接结果里的公共属性列写了两遍,丢分很可惜。连接和选择、投影的组合是个套路题。比如要查“计算机系学生的学号和姓名”,这个需求涉及两步:选择——把系别为计算机的学生挑出来,投影——只要学号和姓名。标准表达式是π学号,姓名(σ系别’计算机’(学生))。这里要注意运算顺序:先做选择把行变少,再做投影把列变少。有些同学先投影再选择,发现投影后系别列没了,选择条件无处依附,这就是顺序写反了。再给一个进阶场景:查询“选修了课程号为C01的学生的学号与成绩”。这时要在选课关系上做选择和投影,而不是在学生关系上做。原因是你需要的信息(课程号、学号、成绩)都在选课关系里。好多同学一看到“学生”两个字就先去查学生表,这是审题出了问题。关系代数表达式和后面SQL的SELECT一样,FROM后面跟哪个关系,取决于你要的数据分布在哪个关系里。3.3 除运算的心法几乎所有同学都卡在这除运算是关系代数里难度最高、也是测验里拉开差距的题目。它的定义是:R÷S,结果是一个新的关系,包含所有在R中出现、且与S中所有元组都匹配的列。不要死记定义,我给学生一个直观的例子。有两张表:选课表(学号,课程号)和课程表(课程号)。选课表÷课程表的结果,是选修了课程表中全部课程的学生学号。也就是说,“选了全部课程的人是谁”这类问题,用除法表达最自然。计算的时候有个方法:先看被除数R的属性集合,再看除数S的属性集合,S的属性集合必须是R的属性集合的子集。结果关系的属性就是R的属性减去S的属性。然后判断哪些取值满足“包含S中的所有值”。比如选课关系选课(学号,课程号),数据有三行:(201, C1)、(201, C2)、(202, C1)。现在要查“同时选修了C1和C2课程的学生”,除数是课程号集合{C1, C2}。我们看学号201对应的课程号是{C1, C2},包含{C1, C2},所以201在结果中。学号202对应的课程号只有{C1},不包含C2,所以202不在结果中。最终结果是学号201。除运算的难点在于它不是一个“一眼就能看穿”的运算,需要你跳出“逐行比对”的思维,上升到“集合包含”的层面。正常情况下,测验里除运算题最多出现1到2题,做不出来别死磕,先把基础题的分保住,再用排除法选答案。4. 典型测验题与解答示范照着这个思路写4.1 选择题概念辨析的三种常见问法选择第一类问法:给出一组概念,让你判断包含关系。比如“超键、候选键、主键”的关系,正确的是主键⊆候选键⊆超键。检查点在于:候选键本身就是超键,主键本身就是候选键。这里的“⊆”是集合包含,主键和候选键是“挑出来的一个”和“候选集合”的关系,不是“属于”而是“包含于”。选择第二类问法:判断关系性质的适用范围。比如“关系中列的次序可以任意颠倒,这体现了关系模型的什么性质”。选“列序无关性”。如果选项里有“数据抽象”,那是三层模式结构里讲的概念,别被干扰项带偏。选择第三类问法:计算类。比如已知R有4行3列,S有5行4列,求R和S做笛卡尔积后结果有多少行、多少列。答案是有20行、7列。这类题考查对笛卡尔积行数和列数公式的理解:行的数量是m×p,列的数量是nq。做的时候注意行和列是分开计算的,别把行数公式用在列数上。4.2 填空题关键字与性质的空缺补全填空题经常这样出:“在关系模型中,____用于唯一标识关系中的一个元组。”答案是主键。这里有个细节要注意:如果题目强调的是“能唯一标识元组的一个或多个属性”,那可能填候选键;如果强调的是“用户选定的、用于标识的”,那填主键。读题时把“唯一标识”和“用户选定”这两个信号词抓住。还有一空是“如果一个外键的值不是被参照关系中的主键值,则它必须为____,前提是它不属于其所在关系的主键部分。”答案是空值或者NULL。这个空我见过很多人填“零”,这是错的。关系模型中的空值表示未知或不存在,不是数字零,也不是空字符串。这是两个完全不同的概念,考试时填“空值”更严谨。再有一种填空:给定两个关系,让填写自然连接结果的属性个数。假设关系A有3个属性,关系B有5个属性,它们有2个同名属性,自然连接结果有几列?答案是35-26列。“减2”是因为两个同名属性在结果中各保留一列,而不再重复两列。这个公式一定要记清楚,它是自然连接和等值连接的直观区别。4.3 关系代数表达式题三步法写不丢分我给学生总结了一套写关系代数表达式的三步法,单元测验和考研题通用。第一步,读懂需求,圈出你要查询的目标属性列;第二步,确定这些属性分布在哪些关系中,决定对哪个关系先做哪种操作;第三步,按“选择→连接→投影”的顺序组织表达式,先过滤行,再合并表,最后裁剪列。举例说明。给定三个关系:学生(学号,姓名,系别),课程(课程号,课程名,学分),选课(学号,课程号,成绩)。要求写“查询计算机系学生选修的课程名”。拆解一下目标:最终要的是“课程名”这个属性,它属于课程关系;限定条件是“计算机系”这属于学生关系;选课关系负责把学生和课程关联起来。所以这个查询至少涉及三个关系的连接。先把学生和选课按学号连接,再把结果和课程按课程号连接。顺序上,可以先把选课和课程连接,再连接学生,也可以先学生和选课连接再连接课程。表达式的骨架是π课程名(σ系别’计算机’(学生⋈选课⋈课程))。注意多个关系连接时,笛卡尔积的选择条件要写清楚,不能只写一个连接条件。标准写法是:π课程名(σ系别’计算机’∧学生.学号选课.学号∧选课.课程号课程.课程号(学生×选课×课程))。用自然连接写法时连接条件隐含,直接写学生⋈选课⋈课程即可。写表达式的过程中,有三件事最容易丢分:一是属性名前没加关系名前缀,比如直接写“学号”但两个关系里都有学号,产生二义性;二是漏了连接条件,只写笛卡尔积;三是顺序反了,把投影写在了选择前面,导致选择条件用到的列已经被裁掉了。这三条我在批改测验时几乎每题都能碰到,大家写完务必自查一遍。5. 错题复盘与常见坑位这些错法我年年见5.1 高频错点速查自己做题时对号入座每年批改单元测验,我都会整理一个高频错点清单,这里分享出来。第一个错点是混淆“关系”和“表”。严格来说,关系是理论概念,表是实现形式。但实际使用中大家习惯混用。测验如果出判断题“关系的逻辑结构就是一张二维表”,这个说法算是对的;但如果出“关系在物理存储上也是二维表结构”,那是错的。物理存储层面有索引、堆文件、压缩等结构,不是简单二维表。第二个错点是参照完整性和外键的关系没有理解透。我遇到过一个很典型的错法:判断“参照完整性要求外键不能为空值”,答案是错的。因为外键可以为空,只要它不属于主键部分。这个空值的含义是“尚未建立关联”,比如新入职的员工还没有分配部门,部门号为空,这是被允许的。第三个错点是用户自定义完整性被误判为实体完整性。比如“成绩必须在0到100之间”这类规则,属于用户自定义完整性,不是实体完整性。实体完整性只针对主键,不要一看到“非空”“唯一”就条件反射选实体完整性。仔细读题,看约束作用在哪个属性上,再下结论。第四个错点,也是最多人踩的坑:关系代数里“选择”和“投影”的先后顺序。我再强调一遍,能用选择先过滤掉的行,一定先过滤。原因是关系代数在理论上不考虑执行效率,但从逻辑上讲,先选择能减少后续运算的中间结果规模。某些题目还专门要求你判断两个表达式是否等价,这时候你就要知道:σ和π有时候可以交换顺序,但前提是选择条件里的属性仍然在投影结果中保留。如果选择条件涉及被投影掉的列,两个表达式就完全不是一回事了。5.2 从单元测验到实际应用关系模型为什么值得学透很多学生考完这一章就把关系模型抛到脑后,觉得后面学SQL才是“实用”的。其实关系模型藏着大量实际面试和工作中的底层逻辑。大家都知道数据库面试题里常出现“Explain执行计划”“索引失效”“事务隔离级别”,但很少有人意识到,索引和表扫描的优化逻辑、外键约束的设计、ORM框架中实体类的设计,都是在关系模型这块地基上长出来的。举几个具体例子。为什么建表时推荐定义主键?因为关系模型要求每个元组唯一,而主键就是实体完整性的体现。为什么设计外键约束?因为参照完整性保证了跨表数据的可靠性——你删一个班级,系统会阻止你删除仍有学生关联的班级,这就是参照完整性在工作中的落地。为什么表设计要满足范式?因为不满足范式会产生数据冗余和更新异常,这在关系模型中对应的是更新异常和数据不一致问题。再打个比方,关系模型就像一栋房子的图纸,SQL是砌墙的工具,MySQL是实际盖起来的楼。你只在干活时学工具能砌出房子,但遇到房子歪了、漏水了、某个房间不能用了,只有懂图纸的人才能精准定位问题在哪面墙上。面试时为什么很多岗位喜欢问数据库基础?因为基础决定了一个人排查问题的深度。5.3 复习节奏与自测方法最后一周怎么规划如果你只有一周就要考这一章,我的建议是前几天以上面的知识点为主,最后三天集中做题。具体安排:第一天把关系的六条性质、三类完整性、键的概念过一遍,做到闭上眼能说出来;第二天专攻关系代数,把并、差、笛卡尔积、选择、投影、连接、除各练个几道;第三天做综合题,把三个关系的连接查询搞熟练;之后每天做一套单元测验题,错题当天订正。自测时有个小技巧:不要只在脑子里想答案,要动手写出来。尤其是关系代数表达式,心里觉得“会”和笔下写得出来是两回事。写完后对照标准答案,不看思路只看结果还不行,还要看表达式里有没有隐含的多余操作、漏掉的条件。我让学生互相批改表达式,效果特别好,因为你给别人挑错的时候,会发现自己从来没意识到的盲区。另外,遇到不确定的判断题,有一个通用的分析框架:先挖出它考的是哪个知识点,再把定义逐字抠一遍,最后看题干有没有附加条件。关系模型这个概念本身并不难,难的是你在考场上能不能把背过的定义,灵活套到一个新的场景里。这个能力只能靠多做题来练。最后再说一点我个人的体会。关系模型的六条性质、三类完整性、八个关系代数运算,每个单独拿出来都不难,难在它们会组合出题。我见过很多学生在单个知识点上没问题,一进入综合题就乱了阵脚。我的建议是,把每一道综合题都当成一个小型数据库设计任务来做:先确定涉及哪些关系,再确定需要哪些运算,最后按逻辑顺序一步步写出来。这个方法在测验里能帮你稳住大分题,在面试里能帮你展现出完整的问题分析能力,一举两得。