数据库原理第三次在线作业核心考点与SQL答题技巧

发布时间:2026/10/19 9:41:05
数据库原理第三次在线作业核心考点与SQL答题技巧
1. 第三次在线作业到底考什么1.1 从画ER图到写SQL作业难度是怎么升级的数据库原理及应用这门课有个很明显的规律前两次在线作业还在帮你热身画个ER图、数几个元组、区分一下实体和属性到了第三次画风突然变成“你得真的会写查询、会拆表、会讲事务”。很多同学第一次拿到第三次在线作业时都有点懵因为题目不再是“请简述关系的性质”而是直接甩一张关系模式让你写出关系代数表达式或者给出业务描述让你把建表和查询SQL完整写出来。第三次在线作业相当于期中型的动手考核覆盖内容通常集中在四块关系代数、SQL语言、函数依赖与范式、事务与并发控制。要是你们学校的前半段课程还讲了视图、索引、完整性约束那这些也经常混进SQL大题里。石油类高校的任课老师还特别喜欢把业务背景换成油气生产、钻井信息、物资库存、学生选课这类数据库美其名曰“贴合专业特色”。所以你不光要会写标准的学生选课SQL还得会换一套表名、换一套字段名之后依然能把语法写对。这类作业的真正目的不是抽查记忆而是逼你把课堂知识转成“可运行的答案”。因为很多在线作业系统会把SQL拖到数据库引擎里实际执行再和你提交的答案做比对。如果你只是写个大概意思比如表名少了个字母、字段名自己取了个顺口的哪怕逻辑全对系统照样判零分。这也是为什么我后面要花一整章讲在线判分和人工批改的差异。1.2 常见题型的知识点地图与分值参考第三次在线作业的题型通常不会太偏基本围绕着这几个方向打转关系代数表达式、SQL的DDL和DML、多表查询与视图、范式判断与分解、事务特性与隔离级别。我按多数课程作业的设置规律整理了一张复习对照表你可以直接拿它当清单用。知识点常见题型准备重点建议用时关系代数写表达式、判断表达式含义、转SQL选择、投影、连接、并差的优先级和符号2小时SQL建表与修改建表、插入、更新、删除、加约束数据类型、主外键、非空、默认值2小时SQL单表与多表查询条件查询、聚合统计、分组过滤、子查询select逻辑执行顺序、连接类型4小时视图与索引创建视图、简单索引视图本质是虚表不能随便更新1小时范式判断与分解判断属于第几范式、分解到3NF或BCNF候选码、部分依赖、传递依赖3小时事务与并发简答ACID、脏读、隔离级别场景化记忆不必死背定义2小时从分值占比看SQL查询的大题通常占一半以上其他知识点以小题和简答为主。很多人喜欢在范式上死磕结果最后没时间写SQL这是很亏的。范式题再难也就是几步推演SQL一旦写错在线系统会直接告诉你结果不匹配一分都没有。所以时间分配上SQL优先范式其次关系代数和事务简答用碎片时间准备就够了。1.3 在线判分和老师手批完全是两回事这一点必须单独拎出来说。在线作业的判分逻辑和纸质作业完全不一样很多同学就是没搞懂这个才在本该拿分的题上翻车。纸质作业里你写“用student表查女生信息”老师一看意思对就给你分。在线作业系统往往不是尤其是SQL题它可能把你的语句放到数据库里跑一遍然后把查询结果和标准结果集比对。表名、字段名、条件阈值、输出列的顺序甚至结果中某个值的字符串格式都可能成为判分依据。关系代数题虽然不一定真的执行但很多系统也做了关键字或表达式匹配你把σ写成中文全角字符、把π写成P系统可能照样认不出来。所以拿到题目第一步不是急着想查询怎么写而是先圈出题面里给定的表名、字段名、别名和条件值。在线作业里“student”和“students”是两个东西“grade”和“score”也不是一回事。你后面所有答案都要严格对着题面里的名字来绝不能自己另取一套。这个细节看着不起眼却是我看过最多的翻车原因。2. 数据库原理核心考点拆解答题前必须搞清的底层逻辑2.1 关系代数先读成一句人话再写符号关系代数看起来全是希腊字母σ、π、⋈、÷好像很高冷其实核心思想特别生活化。关系就是一张表选择就是横向筛行投影就是纵向取列连接就是把两张表按共同列拼在一起。每次写完一个关系代数表达式你都应该能把它读成一句人话而不是一堆符号的排列。比如π学号(σ性别女(学生))读出来就是先到学生表里找性别为女的那些行再从这些行里取出学号列。这样倒过来读能帮你发现一个特别经典的低级错误先投影再选择结果发现选择条件里的列已经被丢掉了。比如要查“选了课的女生学号”你写成π学号(σ性别女(学生))读出来就是“先找女生再取学号”完全没提选课表系统当然不认。正确做法是先连接再过滤再投影π学号(σ性别女(学生⋈选课))从底层逻辑上说关系代数五类基本运算是并、差、选择、投影、笛卡尔积连接和除都是在此基础上扩展出来的。答题时如果题目明确要求“用关系代数表示”就不要用标准的扩展符号以外的运算符尽量用σ、π、⋈、∪、−这些常见符号。还有一个小提醒所有字符都切到英文半角状态否则表达式表面看起来对系统匹配时可能直接翻车。2.2 SQL查询按逻辑执行顺序倒推where和having不会再用错SQL语句的阅读顺序和真正的执行顺序差别很大这是很多人在线作业里踩坑的根源。一条select语句的逻辑执行顺序是from → where → group by → having → select → order by。这个顺序决定了哪些条件该放在where哪些必须放在having。举个例子题目说“查询平均成绩大于80分的学生编号”。很多同学凭直觉写select sno from sc where avg(grade) 80 group by sno这个语句只要放进数据库大概率会报错“聚合函数不允许出现在where中”。为什么因为where是在分组之前执行的它处理的是每一行原始记录而avg是分组之后才能算出来的值。正确写法是把条件放到having里select sno from sc group by sno having avg(grade) 80理解这个逻辑有个特别好的生活类比先把一堆成绩单按学生分成几摞再检查每一摞的平均分有没有过80而不是在发成绩单之前就去算平均分。在线作业里SQL题还经常考察连接查询和子查询。如果题目没有特别要求优先写连接因为连接思路更直观也更容易被数据库优化器处理。但要注意多表连接时如果表之间没有加连接条件会变成笛卡尔积结果行数爆炸在线系统比对结果时直接就是“Failed”。所以每次写多表查询写完先数一下from里有几张表再看where或者on里是否给足了连接条件。2.3 范式判断找候选码、查部分依赖、查传递依赖范式题看上去变化很多其实核心动作就三个找候选码查非主属性对候选码有没有部分依赖查非主属性对候选码有没有传递依赖。把这三步走完绝大多数题目都能解出来。先解释几个关键词。候选码是最小的能唯一确定一条元组的属性集合主属性是候选码里的任何一个属性非主属性是不在任何一个候选码里的属性。部分依赖指的是某一个非主属性只依赖候选码的一部分这种情况只有当候选码是复合属性组时才会发生。传递依赖指的是从候选码出发先推到另一个属性再由这个属性推出目标非主属性中间隔了一手。我以前给学生改过一道很典型的题关系模式R(学号, 课程号, 成绩, 学分)函数依赖是学号和课程号决定成绩课程号单独决定学分。候选码显然是(学号, 课程号)因为只有这两个合起来才能唯一确定一行成绩。学分这个非主属性只依赖课程号而课程号只是候选码的一部分所以这就是部分依赖。这时候R只满足1NF需要拆表把成绩和学号、课程号放一起变成R1(学号, 课程号, 成绩)把学分和课程号单独放一起变成R2(课程号, 学分)。这样每个表里的非主属性都完全依赖码达到2NF。如果R2里没有传递依赖那它也满足3NF。在线作答时范式题最忌讳只写结论不写过程。哪怕题目只是要求判断第几范式最好也顺手写出“候选码是什么、存在什么依赖、为什么”这几句话。因为自动判分系统即使看不懂你的推理也会提取关键词去匹配候选码和依赖名称写全了踩中得分点的概率就高很多。2.4 事务与隔离级别用场景记忆代替死背概念事务这块最常考的就是ACID四大特性和并发控制问题。ACID四个字母看着抽象用转账场景一解释就全通了。原子性是说转账要么全部成功要么全部失败不能出现钱扣了但对方没收到的情况一致性是说转账前后总金额不变隔离性是两个转账操作不能互相破坏中间状态持久性是转账一旦提交结果就不会丢。并发控制里最常出现的三个名词是脏读、不可重复读、幻读很多同学背了定义还是分不清。我的经验是每记一个术语就配一个具体场景。脏读就是一个事务读到另一个事务还没提交的数据。比如一个采油厂员工先修改了某口油井的当天产量还没提交事务另一个统计员立刻读取了这个数字去做报表结果前一个事务因为录入错误回滚了报表上就用了一个“不存在”的产量。不可重复读是同一个事务中两次读取同一行数据结果因为别人提交了修改而变得不一样。幻读则是同一事务两次执行同样的范围查询结果行数多了或少了就像出现了幻觉一样。答题时如果有隔离级别的简答你不需要背大段的定义只要抓住“某个级别能避免什么问题还会留下什么问题”这条路子即可。比如读已提交能避免脏读但不可重复读和幻读仍然可能发生可重复读能避免脏读和不可重复读但幻读仍可能发生串行化最严格三个问题都能解决但并发度最低。这样组织答案踩分点比空谈概念清晰得多。3. 实操过程一套能直接照抄的作业答案写法3.1 典型题目分析一个贴近石油业务的学生选课库在线作业的大题一般都会给一个完整的业务描述让你从建表开始一步一步写完。我在这里构造一个贴近石油类高校教学风格的场景把常见的题目要求都串起来。假设业务背景是某高校需要管理石油工程、油气储运等专业的学生选课信息。学生有学号、姓名、性别、专业课程有课程号、课程名、学分学生选修课程后产生成绩。要求你设计三个表并完成若干查询任务。这种题考察的就是你能不能把业务描述变成正确的表结构。我的做法是先在草稿纸上列一张“实体-字段清单”每个实体标注主键和外键。学生表主键是学号课程表主键是课程号选课表主键是学号和课程号的组合同时学号和课程号分别引用前两张表。把这个清单写清楚建表SQL就是照抄了不会漏外键。3.2 从建表到查询的完整SQL示例下面给出一套可以直接参考的SQL写法注意表名和字段名就是常见的“学生-课程-选课”三表结构在线作业里如果换了名字你只需要整体替换。create database petro_student_db; use petro_student_db; create table student ( sno char(10) primary key, sname varchar(20) not null, sex char(2), major varchar(30) ); create table course ( cno char(6) primary key, cname varchar(40) not null, credit numeric(3,1) ); create table sc ( sno char(10), cno char(6), grade numeric(5,2), primary key (sno, cno), foreign key (sno) references student(sno), foreign key (cno) references course(cno) );建表之后通常跟着插入数据的题目。插入时最容易错的是主键重复和违反外键约束。比如往选课表插数据前必须先确保学生表里已经有这个学号、课程表里已经有这个课程号。有的同学先把选课记录插进去再补学生信息数据库立刻报错。查询部分常见的几种问法是这样处理的查询“石油工程”专业男生的学号和姓名select sno, sname from student where major 石油工程 and sex 男;查询每门课程的平均成绩按课程号排序select cno, avg(grade) as avg_grade from sc group by cno order by cno;查询某个学生选修的全部课程名需要连接三张表select cname from student join sc on student.sno sc.sno join course on sc.cno course.cno where sname 张三;写多表连接前我习惯先在心里过一遍逻辑执行顺序from之后先把student、sc、course三张表按on条件连成一张大表where再筛出张三最后select取课程名列。只要这个顺序不断火药哪怕写出来的SQL不那么优雅结果也是对的。视图的题目也很常见比如创建“石油工程专业学生选课信息”视图create view petro_student_course as select student.sno, sname, cname, grade from student join sc on student.sno sc.sno join course on sc.cno course.cno where major 石油工程;在线作业里写视图一定要先检查表结构里有没有对应的表名和字段否则被数据库以“表或视图不存在”的直接弹错。3.3 范式分解演示从候选码到最后无损分解关系模式这块我在批改过程中发现只要题目给的属性一多很多人就开始乱拆表。其实范式分解有固定套路一步一步写完全能拿分。看一个综合例子。关系模式R(A, B, C, D, E)函数依赖集合FA → BA → CC → DD → E。第一步找候选码。A能推出B和CC又能推出DD又能推出E所以从A出发能推到所有属性候选码就是A。第二步看2NF。因为候选码只有一个属性A不存在非主属性只依赖候选码的一部分这种情况所以R至少满足2NF。这里有很多人绕不过来一直纠结“主属性有五个还不止一个”这是理解错了。主属性是候选码里的属性候选码只有一个A那么主属性就是AB、C、D、E都是非主属性。第三步看3NF。C由A直接决定但C又能决定DD又能决定E这就是典型的传递依赖A → C → D → E。既然存在传递依赖R就不满足3NF。分解的时候按传递链来拆。先把A推出来的核心部分和直接依赖放一起得到R1(A, B, C)再把C推出D放到R2(C, D)最后把D推出E放到R3(D, E)。检查一下R1包含候选码A连接后能无损恢复原关系函数依赖A → B、A → C在R1C → D在R2D → E在R3全部保留。这样分解是正确的3NF。在线填答案时我建议把每个阶段的候选码、依赖类型、分解结果写在同一行关键词里比如“候选码A存在传递依赖C→D→E分解为R1(A,B,C)R2(C,D)R3(D,E)”。这样就算系统只做关键词匹配你也能踩中一大半。3.4 事务简答题的三段式组织套路事务简答看起来要写好多字其实在线作业的判分只看关键词所以我的建议是“短平快”组织答案。比如题目问“读已提交隔离级别能避免哪种并发问题仍会出现哪些问题”你可以按这个模板写第一句读已提交避免脏读因为一个事务只能读取到其他事务已经提交的数据。第二句读已提交仍可能出现不可重复读因为同一事务中两次读取同一记录期间其他事务提交了修改导致两次读取结果不一样。第三句读已提交也可能出现幻读因为同一事务两次执行范围查询期间其他事务插入了新记录导致结果集行数变化。如果题目还问“应该什么级别才能完全解决”就补一句可重复读能解决不可重复读串行化能解决全部三类并发问题但并发度最低。写这种答案最忌讳长篇大论。在线系统如果对文字答案设置了上限你写太多反而可能把关键判分词挤出有效区域。先把“脏读、不可重复读、幻读、串行化”这五个词放到句子的显眼位置再补充一句场景解释已经是性价比很高的答法。4. 在线作业常见问题与排查技巧实录4.1 系统判错的5个隐藏原因我见过太多同学把SQL写到本地工具里完全能跑粘贴到在线作业平台却被判零分。问题往往不在SQL本身而在一些隐藏的细节。按踩坑频率最高的是这五类问题类型典型例子解决办法表名或字段名与题面不一致题面叫student你写students抄题面原词不要自己顺口改中文标点或全角符号逗号、分号、圆括号用了中文状态全程切英文半角输入多余或缺失结尾分号多语句任务里每条都加分号平台只跑第一条按题目要求决定是否加分号输出列名或顺序不符题目要求学号、姓名你写成姓名、学号先看题面要求的输出列再写select字符串与NULL混用插入空值时写了而不是NULL看字段设计可空字段用NULL第一条尤其要提醒。在线SQL题的表名和字段名都是判分参照你哪怕只是多一个s系统就认为你查了一张不存在的表。比起在本地连数据库宁可多花两分钟把题面的表结构抄到草稿纸上再对着抄好的名字写代码。4.2 SQL查询没有结果的排查顺序在线作业系统不会告诉你SQL哪里错它只说“结果不匹配”或“执行失败”这时候你得自己排雷。我建议按下面的顺序一条条查。先查逻辑执行顺序。把SQL拆开from后面是哪些表where过滤了什么group之后有没有havingselect最后才取列。如果你把一个聚合函数写到where里基本就是这步出问题。再查连接条件。from里有两张表就要有对应的连接条件否则就是笛卡尔积查出来的行数大概率不对。再查数据类型和常量写法。字符型和日期型要加单引号数字不要加单引号“1”和1在某些数据库里类型敏感。最后查分组字段。如果select里出现了某个字段但group by里没有数据库会报错尤其是现在很多在线平台用的数据库版本对分组规范要求很严。实际上排查SQL最有效的方法不是盯着屏幕看而是把语句拆成一小段一小段执行。先只查一张表确认数据长什么样再逐步加join和where。这样定位错误通常不会超过五分钟。4.3 范式题最容易纠结的几个判定细节范式题不仅新手容易错很多学了两遍的人也会在几个细节上反复犹豫。我把最常见的纠结点整理出来。第一部分依赖只可能出现在复合候选码的情况下。如果候选码只有一个属性那所有非主属性都是整个候选码决定的不存在部分依赖。所以看到候选码是单一的可以直接写“满足2NF”不用瞎猜。第二主属性不是“候选码里那个最像主键的属性”而是候选码里的任意一个属性。比如候选码是(学号, 课程号)那么学号和课程号都是主属性成绩才是非主属性。区分主属性和非主属性是判断3NF和BCNF的前提这个一旦搞错结论基本全错。第三传递依赖里的中间属性要足够“中间”。如果你发现A → B而B又能决定C但B是候选码的一部分或B本身就是主属性这时候的依赖不叫传递依赖还要回到BCNF去判断。在线作业常考的通常比较简单候选码是AB、C都是非主属性A → B → C就是标准的传递依赖。第四分解之后一定要检查候选码是不是留下来了。如果分解后的某个关系模式不包含原关系的候选码连接起来就不能恢复原数据这叫有损分解在3NF题目里是要扣分的。很多同学拆完表觉得功能依赖保持就行了忘了查候选码结果被判错误。4.4 提交前的最后检查清单提交在线作业之前我建议你过一遍下面的检查清单而不是点完“提交”才发现问题。第一所有SQL在本地数据库工具执行过一遍确认没有语法错误和运行错误。在线平台和你本地的数据库版本可能有细微差异但语法级错误在哪都躲不过。第二检查关系代数表达式的符号是否全半角。σ、π、⋈这些符号如果是从网页复制来的容易出现字体问题最好自己用英文输入法打一遍。第三范式分解题确认候选码写出来了函数依赖对应关系写清楚了。第四事务简答题检查关键词是否覆盖脏读、不可重复读、幻读、隔离级别、ACID。第五把整份答案备份到本地。最后这条最现实。在线作业偶尔会因为网络波动或页面超时导致草稿丢失辛苦写了俩小时一刷新全没了。不管平台有没有自动保存我都建议你在本地文档里同步存一份文件名标好题目编号。这样即使平台抽风你也能快速重新粘贴不至于心态崩掉。5. 批改过很多次作业之后我最想提醒你的事5.1 高分和低分的差距到底在哪里我做过一段时间数据库课程的作业辅导看过大量在线作业的答题情况。最后发现真正拉开分数的根本不是智商而是两点第一有没有把每条SQL都实打实跑一遍第二有没有顺着判题规则组织答案。那些拿高分的同学普遍有一个习惯拿到题目后不急着写先在本地数据库工具里建一张一样的表塞几个测试数据然后一遍遍跑自己的查询。他们不是不想直接抄答案而是知道在线判分系统只认“能跑通的结果”不认“看起来对的意思”。一个SQL跑出正确结果集胜过你在脑海里推演十遍。而那些总是差一点分的同学问题通常不是不会写而是太相信自己的第一印象。表名随手改、输出列顺序随意调、where和having凭感觉放结果就是在线平台反复提示结果不匹配。其实每次判负都说明不了“你不行”只能说明“你和系统的规则还没对齐”。5.2 一个随时能用的答题小技巧最后分享一个我自己一直在用的方法尤其适合在线作业这种时间紧、判分严的场景。拿到任何一道SQL题先在草稿纸上写三行要查哪张表要取哪些列过滤条件是什么。如果要分组统计再加一行“按什么分组、分组后过滤条件是什么”。然后把这三行内容套到SQL模板里select 要取的列 from 表名 where 行级过滤条件 group by 分组列 having 组级过滤条件 order by 排序列;关系代数题也类似先把条件里的名词圈出来决定哪些是选择、哪些是投影、哪些需要连接再动手写符号。范式题则固定按“候选码→部分依赖→传递依赖→分解”四步走。这套思路不复杂但能让你少走很多弯路。把这些步骤练成习惯之后你会发现第三次在线作业也没那么可怕它只是检测你是否愿意静下心来老老实实写一遍能跑通的答案而已。