ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

王珊《数据库系统概论》第5版答案:关系代数与范式思维训练指南

王珊《数据库系统概论》第5版答案:关系代数与范式思维训练指南

简介:本资源是《数据库系统概论(第5版)》王珊、萨师煊主编教材的配套课后习题详细答案,面向高校计算机、软件工程、信息管理等专业本科生及数据库初学者,用于巩固关系模型、关系代数、SQL语言等核心理论知识,辅助课程学习与期末备考。文件为单个Word文档(.doc),共1份,大小588KB,内容覆盖第2章关系数据库与第3章SQL语言全部重点习题,含关系模型三要素、完整性约束判定、等值连接与自然连接辨析、SPJ关系代数表达式推导、SQL建表与多表查询语句编写等典型题型的完整解答与解析说明。已有1723人学习下载,答案排版清晰、步骤详尽,可直接用于对照自查、理解解题逻辑、掌握规范化书写格式,是夯实数据库理论基础、提升SQL实践能力的实用参考资料。

1. 《数据库系统概论》第5版答案(王珊版)到底是什么?——它不是“抄作业指南”,而是一把帮你拧紧数据库思维螺丝的扳手

你是不是也经历过这样的深夜:对着“关系代数”四个字发呆,手边是密密麻麻的π(投影)、σ(选择)、∞(连接)符号,像看天书;写完一条SQL,运行出来结果空空如也,翻遍教材却找不到错在哪;考试前狂背“BCNF定义”,考场上看到“判断R是否属于3NF”还是脑子一 blank……别慌——这份标着“王珊版第5版答案”的.doc文件,根本不是什么“速成秘籍”,它是一套经过千锤百炼的思维校准器。

打个比方:学游泳,教练不会只给你一张“标准泳姿分解图”,而是先让你泡在浅水区反复练呼吸、漂浮、划水节奏。这份答案文档,就是那个“浅水区”。它不替你划水,但每一道题后都附着清晰的推演路径:为什么这道题要用“除运算(÷)”而不是“连接(∞)”?为什么“外码可以为空”不是bug,而是设计上留出的弹性接口?为什么视图能当“数据面具”用,而基本表才是真身?它把教科书里那些抽象定义——比如“函数依赖”“传递依赖”“参照完整性”——全拆解成可触摸的逻辑链条,让你看清每个齿轮怎么咬合、哪颗螺丝松了会导致整个系统异响。

很多人误以为这是“答案集”,拿来对完选择题就扔一边。但真正用过的人知道:它的价值不在“结果”,而在“过程注释”。比如第2章第6题求“至少用了S1所供全部零件的工程号”,答案里不仅给出关系代数表达式πJno,Pno(SPJ) ÷ πPno(σSno='S1'(SPJ)),更关键的是那句小字说明:“除法本质是‘全称命题’的数学表达——要找所有满足‘对S1供应的每一个PNO,该JNO都存在对应记录’的JNO”。这句话,瞬间就把一个冷冰冰的符号,变成了你脑子里能调用的判断逻辑。它解决的不是某道题,而是你面对任何新查询时,第一反应是“该用哪种操作”而不是“这题我见过吗”的底层能力。如果你正被数据库的“玄学感”困住——总觉得概念飘在空中、SQL写得心虚、范式判断像掷骰子——这份资源,就是帮你把脚踩回地面的那块踏板。


2. 它为什么存在?——不是为应付考试,而是为对抗数据库学习中三大“认知断层”

数据库入门最让人崩溃的,从来不是语法有多难,而是概念之间像断开的电路,明明学了A,却连不上B,更想不到C。这份答案文档的存在,正是为了焊接这些关键断点。它不堆砌理论,而是用“问题-推演-结论”的闭环,强行打通三处最容易卡死的认知断层。

2.1 断层一:从“数学符号”到“真实数据操作”的失重感

初学者看到关系代数,第一反应常是:“这不就是集合论换了个马甲?”但很快发现:书上说“投影πSno(σJno=‘J1’(SPJ))”,你照着写,结果却漏了去重(DISTINCT),或者没意识到σ条件里字符串要加单引号。这种“纸上谈兵”和“实战翻车”的落差,根源在于缺乏操作意图到符号实现的映射训练。

这份答案文档,在每道关系代数题后都强制补上“执行逻辑”注释。比如第2章第6题第1问:

问题:求供应工程 J1 零件的供应商号码 SNO
答案:πSno(σJno=‘J1’(SPJ))
关键注释:

  • σJno=‘J1’是“筛选”动作:像用筛子滤掉所有JNO≠'J1'的行;
  • πSno是“提纯”动作:只留下SNO这一列,其他列(PNO, QTY)全部丢弃;
  • 易忽略点:关系代数默认结果无重复元组,但实际SQL需显式写SELECT DISTINCT Sno,否则可能因SPJ表中同一SNO供应多个J1零件而重复出现。

再看SQL实现部分:

-- 正确写法(带DISTINCT) SELECT DISTINCT Sno FROM SPJ WHERE Jno='J1'; -- 错误写法(漏DISTINCT,可能重复) SELECT Sno FROM SPJ WHERE Jno='J1';

参数说明:DISTINCT不是可选项,而是关系代数中“集合无序无重”特性的强制落地。没有它,SQL结果集就违背了关系模型的数学根基——它不是一个列表,而是一个数学集合。

这种“符号→动作→现实约束”的三段式拆解,把抽象运算拉回数据库引擎的真实执行场景,让你写的每一行代码,心里都有底。

2.2 断层二:从“语法正确”到“语义安全”的盲区

很多人能写出语法无误的SQL,却栽在数据逻辑上。比如第4章安全性习题7(c):“每个职工只对自己的记录有 SELECT 权力”。有人直接写GRANT SELECT ON 职工 TO ALL,看似省事,实则大错——这等于把所有人数据全摊开。而答案给出的方案是:

GRANT SELECT ON 职工 WHEN USER() = NAME TO ALL;

核心逻辑:WHEN USER() = NAME是一个行级安全策略(Row-Level Security)的雏形。它让数据库在每次查询时自动注入过滤条件WHERE NAME = CURRENT_USER,相当于给每条SELECT语句悄悄加了一把锁。用户A查SELECT * FROM 职工,系统实际执行的是SELECT * FROM 职工 WHERE NAME = 'A'。

这个细节揭示了一个关键认知:数据库权限不是“开关”,而是“过滤器”。它不决定你能不能执行SELECT,而是决定SELECT能“看到哪些行”。这份答案文档在每处权限设计题后,都强调“策略生效的粒度”——是整张表?某几列?还是某几行?它逼你思考:我的授权,是在放行操作,还是在划定数据疆界?

2.3 断层三:从“孤立知识点”到“系统性防御”的割裂

数据库的完整性、安全性、并发控制,常被拆成三章讲,导致学生以为它们是平行关系。但这份答案在第5章(完整性)和第4章(安全性)的交叉题中,刻意制造对比:

第5章习题2:完整性 vs 安全性区别?
答案直击要害:

  • 完整性防的是“自己人犯傻”:比如录入年龄-10岁、把主键设为空、删掉被引用的部门——这些操作者可能是开发、DBA,动机是疏忽或逻辑错误;
  • 安全性防的是“外人捣乱”:比如黑客爆破密码、员工越权查薪资、离职人员窃取客户库——这些操作者是恶意第三方,动机是窃取或破坏。
    类比:完整性像汽车的安全气囊和ABS系统——防止驾驶员自己操作失误导致事故;安全性像车门锁和防盗报警——防止小偷撬门偷车。

这种对比不是为了考试答题,而是帮你建立数据库防护的立体地图:当你设计一个新系统时,会本能地问:“这里的数据,哪些风险来自内部逻辑漏洞(该加CHECK约束?该设FOREIGN KEY?),哪些风险来自外部越权(该建VIEW隔离?该配GRANT权限?)”。它把零散知识点,焊成了你脑中的防御体系。


3. 它和网上那些“数据库速成课”“SQL面试宝典”有什么本质区别?——一份答案文档的“非典型价值”

市面上充斥着两类资源:一类是“百科全书式”的理论大全,术语堆砌如山,读完更晕;另一类是“菜谱式”的技巧合集,教你SELECT * FROM 表 WHERE 1=1这种万能句式,却不说为什么。而这份王珊版答案文档,走的是第三条路——它是一份以问题为锚点、以推演为路径、以认知校准为目标的“思维训练日志”。它的区别,藏在三个“不”里。

3.1 它不追求“覆盖所有题型”,而专注“击穿核心题眼”

你可能注意到,文档里第2章习题3、第3章习题2等题目标着“(略)”。这不是偷懒,而是刻意聚焦。它把火力集中在最易混淆、最常考、最能暴露思维漏洞的题目上。比如:

  • 为什么第2章第7题(等值连接 vs 自然连接)必答?
    因为90%的SQL新手写多表查询时,第一反应是FROM A, B WHERE A.id=B.id,却不知这本质是笛卡尔积+筛选,性能灾难的温床;而JOIN ... ON才是明确的连接意图。答案用一句话点破:“自然连接是等值连接的‘洁癖版’——它要求同名字段自动匹配,且结果自动去重列”。这比背十种JOIN类型更有用。

  • 为什么第6章第7题(二目关系必属BCNF)要详细证明?
    因为这是范式理论的“锚点案例”。当你理解了“只有两个属性,就不可能存在非主属性对码的部分/传递依赖”,再看三属性表的3NF判断,思路就清晰了——它给你一把尺子,去量任何新关系的范式层级。

3.2 它不提供“标准答案模板”,而展示“思考岔路口的抉择”

很多资料给的答案像判决书:“第X题,答案是Y”。而这份文档,在关键题后标注了常见错误路径及归因。例如第3章习题4(4):“求没有使用天津供应商生产的红色零件的工程号JNO”。

错误解法:SELECT JNO FROM SPJ WHERE JNO NOT IN (SELECT JNO FROM SPJ,S,P WHERE S.CITY='天津' AND P.COLOR='红' AND S.SNO=SPJ.SNO AND P.PNO=SPJ.PNO);
陷阱提示:NOT IN子查询若返回NULL,整个条件恒为FALSE!因为X NOT IN (1,2,NULL)等价于X!=1 AND X!=2 AND X!=NULL,而X!=NULL永远为UNKNOWN(三值逻辑)。
正确解法:用NOT EXISTS重写,或确保子查询WHERE条件排除NULL。

这种“错在哪→为什么错→怎么改”的三段式,比正确答案本身更珍贵。它把你从“做对题”的层面,拉升到“预判坑”的层面——这才是工程师的核心能力。

3.3 它不鼓吹“技术炫技”,而强调“设计背后的业务契约”

最体现功力的,是它把冰冷的技术规则,还原成活生生的业务约束。看第5章习题6的建表语句:

CREATE TABLE EMP ( Empno NUMBER(4), Ename VARCHAR(10), Age NUMBER(2), CONSTRAINT C1 CHECK (Age <= 60), -- 业务规则:法定退休年龄上限 Job VARCHAR(9), Sal NUMBER(7,2), Deptno NUMBER(2), CONSTRAINT FK_DEPTNO FOREIGN KEY(Deptno) REFERENCES DEPT(Deptno) -- 业务规则:员工必须归属有效部门 );

答案旁注:CHECK (Age <= 60)不是随便写的数字,它对应《劳动法》关于劳动者年龄的强制性规定;FOREIGN KEY也不是技术装饰,它保障“不能创建一个挂在空气中的员工”——这是HR系统最基础的业务契约。

当技术细节被赋予业务意义,学习就不再是记忆,而是理解。你会自然追问:“如果公司允许返聘专家,这条CHECK要不要改?”“如果部门临时撤销,CASCADE DELETE会不会误删员工?”——问题一旦从“语法对不对”升级为“业务合不合理”,你的数据库思维才算真正长出了牙齿。


4. 常见误区与易混概念辨析:初学者最常踩的5个“逻辑深坑”

数据库学习最大的障碍,往往不是知识空白,而是已有认知的顽固偏差。这份答案文档像一位严厉又耐心的导师,在你最容易滑倒的地方,提前铺好防滑垫。以下是初学者最常混淆的5组概念,每一条都按“易混点→为什么混→怎么区分”展开,直击痛处。

4.1 易混点:关系代数里的“连接(∞)”和SQL里的“JOIN”是同一个东西?

为什么混:教材常把两者并列讲解,符号相似(∞ vs JOIN),都用于关联多张表,导致学生以为只是“不同语言的写法差异”。
怎么区分:

  • 关系代数∞是纯数学运算:它严格要求“连接条件必须是等值比较(A=B)”,且结果包含所有参与表的列(无列去重);
  • SQL JOIN是工程化封装:它包含多种语义——INNER JOIN(等值连接)、LEFT JOIN(保留左表所有行)、CROSS JOIN(笛卡尔积)。更重要的是,JOIN ... ON后的条件可以是非等值(如ON A.age > B.min_age),这在关系代数中根本不存在!

验证方式:试着用关系代数表达“列出所有员工及其所在部门名称,包括没分配部门的员工”。你会发现,关系代数没有原生LEFT JOIN,必须用R - πR*(R ∞ S)这种绕弯子方式模拟,而SQL一行LEFT JOIN DEPT ON EMP.Deptno = DEPT.Deptno就搞定。本质区别:关系代数是理论模型,SQL JOIN是面向工程的语法糖。

4.2 易混点:视图(View)就是“保存起来的SELECT语句”,所以它和普通表一样能增删改?

为什么混:SQL里CREATE VIEW v AS SELECT ...语法太像建表,且某些简单视图确实支持UPDATE,让学生误以为“视图即表”。
怎么区分:

  • 视图是虚表,无物理存储:它只存定义(SELECT语句),不存数据。每次查询视图,数据库都实时执行其定义语句;
  • 可更新性有严苛限制:答案文档第3章习题8明确指出——仅当视图是“基本表的行列子集”(即SELECT col1,col2 FROM table WHERE condition,无聚合、无DISTINCT、无JOIN)时,才可能更新。一旦含SUM()、GROUP BY或多表连接,更新必然失败。

血泪经验:某开发者为简化报表,建了CREATE VIEW sales_summary AS SELECT dept, SUM(amount) FROM sales GROUP BY dept,然后试图UPDATE sales_summary SET SUM(amount)=1000——报错ORA-01732: data manipulation operation not legal on this view。根源就是混淆了“视图能查”和“视图能改”。记住:视图是数据的“窗口”,不是数据的“副本”。

4.3 易混点:外码(Foreign Key)的值为空(NULL),是因为“数据缺失”,所以应该尽量避免?

为什么混:实体完整性强调“主码不能为空”,学生顺理成章认为“所有码都不能空”,把NULL等同于“脏数据”。
怎么区分:

  • NULL在参照完整性中是合法状态,代表“未知”或“不适用”。答案文档第2章第5题明确解释:“若F是外码,且F本身不是主属性,则可以取空值”。
  • 业务场景决定NULL是否合理:
    • ✅ 合理:员工表中manager_id外码指向经理表。新入职员工暂无直属经理,manager_id=NULL合理;
    • ❌ 不合理:订单表中customer_id外码指向客户表。一个订单没有客户?这违反业务本质,应设为NOT NULL。

关键口诀:主码空=自杀,外码空=待定。判断依据永远是业务逻辑,而非技术洁癖。

4.4 易混点:数据库“安全性”和“完整性”都是防数据出错,所以措施可以通用?

为什么混:两者都涉及“约束”“检查”“拒绝”,且教材常相邻讲解,学生容易合并同类项。
怎么区分:

维度安全性(Security)完整性(Integrity)
防范对象外部未授权用户(黑客、越权员工)内部合法用户(开发、DBA、应用)
违规动机恶意(窃取、篡改、删除)无意(逻辑错误、输入疏忽、程序Bug)
技术手段GRANT/REVOKE、视图、加密、审计PRIMARY KEY、FOREIGN KEY、CHECK、触发器
失败后果数据泄露、系统瘫痪业务逻辑崩坏、报表失真、决策错误

例子强化:给财务人员GRANT SELECT ON salary_table TO fin_user是安全性控制;在salary_table上加CHECK (salary > 0)是完整性控制。前者管“谁能看”,后者管“数据是否合理”。

4.5 易混点:范式(1NF/2NF/3NF)是“越高越好”,所以设计表时必须一步到位到BCNF?

为什么混:教材强调“高范式消除冗余”,学生误以为“范式越高,系统越优”,盲目追求BCNF甚至4NF。
怎么区分:

  • 范式是平衡的艺术,不是攀比的指标。答案文档第6章第11题点明:“第七题中设计的关系模式都只有一个码……所以属于BCNF,不会发生更新异常”。这句话的潜台词是:只有当存在‘更新异常’风险时,升范式才有意义。
  • 反模式警告:为达BCNF,把一个“订单-商品”表硬拆成orders、items、order_items三张表,看似规范,但每次下单要3次INSERT+事务,而业务要求“秒级下单”。此时,适度冗余(如在orders表存item_name)反而是更优解。

黄金法则:先保证业务正确性(完整性),再优化数据结构(范式),最后考虑性能(反范式)。没有业务场景的范式,都是空中楼阁。


5. 什么时候该用它?什么时候该放下它?——一份务实的使用指南与我的血泪教训

这份.doc文档绝非万能钥匙,用错了地方,反而会加固你的思维牢笼。它的价值,只在你主动把它当作“思维手术刀”,而非“答案复印机”。下面结合真实场景,说清它的最佳使用时机、绝对禁忌,以及我踩过的坑。

5.1 最佳使用场景:当你陷入“知道定义,却不会迁移”的困境时

这是它最不可替代的时刻。比如你刚学完“函数依赖”,教材定义背得滚瓜烂熟:“X→Y表示X值相等则Y值必相等”。但拿到一个新表Student(Sno, Sname, Dept, Dhead),其中Dept→Dhead(系名决定系主任),你却卡壳:

  • ❌ 错误尝试:直接套定义,“Sno→Sname 是函数依赖,所以是2NF”——忽略了Dept→Dhead这个隐藏依赖;
  • ✅ 正确路径:打开答案文档第6章习题2,看它如何分析学生表的最小函数依赖集:Sno→Sname, Sno→Dept, Dept→Dhead,进而指出Sno→Dhead是传递依赖(因Sno→Dept且Dept→Dhead),故不满足3NF。

我的教训:去年做课程设计,我设计了一个Course(Cno, Cname, Teacher, Tphone)表,想当然认为Cno是主码就万事大吉。直到上线后发现:同一老师教多门课,Tphone被重复存储,且老师换号要改多行。我翻出这份答案,对照第6章范式例题,才明白Teacher→Tphone是非主属性对码的传递依赖,必须拆出Teacher(Tno, Tname, Tphone)表。从那以后,我每次设计新表,都强制走一遍“找所有函数依赖→画依赖图→检查传递→判断范式”流程,哪怕多花10分钟。希望帮到你。

5.2 绝对禁忌:当你把它当“SQL调试器”或“考试押题库”时

这是最危险的用法。文档里SQL示例(如SELECT DISTINCT Sno FROM SPJ WHERE Jno='J1')是教学切片,不是生产环境模板。

  • 调试陷阱:文档用DISTINCT解决关系代数去重,但真实业务中,DISTINCT可能掩盖深层问题。比如SELECT DISTINCT customer_id FROM orders WHERE status='shipped'返回1000个ID,但你真正需要的是“近30天发货客户数”,却忘了加AND order_date >= '2023-01-01'。文档不会提醒你时间范围,它只负责逻辑正确。
  • 考试陷阱:文档答案基于王珊教材第5版,但高校考题常结合新场景(如加入JSON字段、时空索引)。曾有同学死记“外码可为空”的结论,遇到题干“订单表中 shipping_address_id 外码指向地址表,但支持虚拟仓单(无实际地址)”,就懵了——其实这就是shipping_address_id=NULL的典型场景,但需要你结合业务理解,而非背结论。

5.3 进阶用法:把它作为“自查清单”,构建你的数据库健康检查表

高手从不依赖文档,而是把它的逻辑内化为自己的检查项。我根据文档各章要点,提炼出一份极简自查表,每次上线新功能前必扫:

检查项对应文档章节一句话自问
数据入口第5章“所有INSERT/UPDATE,是否通过CHECK约束/触发器校验了业务规则(如年龄≤60)?”
关联逻辑第2、3章“多表JOIN时,是否确认了连接条件的语义?用LEFT JOIN还是INNER JOIN?NULL如何处理?”
权限边界第4章“当前用户执行此SQL,是否只访问了被GRANT的列和行?视图是否隐藏了敏感字段?”
范式风险第6章“这张表是否存在重复数据?修改某字段(如老师电话)是否要改多行?是否存在‘删了老师,学生记录也消失’的风险?”
查询健壮性第3章“WHERE条件中是否用了= NULL(应为IS NULL)?NOT IN子查询是否可能返回NULL?”

这份表没有一行代码,但它让我在写第一行SQL前,就先想清楚数据的来龙去脉。它不是文档的替代品,而是文档思维的结晶。当你能把这些检查项变成肌肉记忆,你就不再需要这份文档了——因为它已长进你的骨头里。

本文还有配套的精品资源,点击获取

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进