Notes of Database Principle for CUMT final examination
Created by HJY, CS 2019-04
Last Update Date: May. 6, 2021

人工管理阶段
文件系统阶段
数据库系统阶段
| 现实世界 | 信息世界 | 计算机世界 |
|---|---|---|
| 实体 | 实体记录 | 记录 |
| 实体特性 | 属性 | 字段 |
| 实体集 | 实体记录集 | 表 |
| 实体标识符 | 标识属性 | 关键字 |
E-R绘图例题
对于工程硕士管理需要掌握信息有:学生现在的工作单位、职务、简历情况。其中简历情况包括开始时间、终止时间、单位、担任职务、证明人。学生在校信息包括学号、学院、专业、入学时间、导师。 学生在校课程信息包括:课程号、课程名、学时、授课教师及成绩。学院包括学院代号、名称、院长。导师包括导师职工号、姓名 、出生日期、职称、研究方向。
答案



例题
- 学生(学号,姓名,性别,学院,专业方向)
- 课程(课程号,课程名,先行课,学分)
- 学习(学号,课程号,成绩)
- 查询同时选修了所有课程的学生的学号
- 查询至少选修1号同学选修的所有课程的学生姓名
- 查询选修了1号同学选修的课程的学生姓名
- 查询同时选修D与M课程的学生学号
- 【书例2-16】查询同时选修D与M课程的学生姓名
- 【书例2-17】查询被所有学生都选修的课程名
- 【书例2-18】查询没有选修任何课程的学生名单和所在学院
- 【课后2-11(5)】没有被任何人选修的课程名(和8对比)
- 【课后2-11(9)】求每个学生没有选修的课程,列出学号、课程号
答案
例题
检索网络方向的学生选修先行课为计算机网络的课程名和课程学分。写出优化前后的语法树。
答案
NOT NULL不允许为空值,UNIQUE该属性上的值不得重复PRIMARY KEY;或者在列出关系模式的所有属性后,再附加一个声明:PRIMARY KEY(<属性1> [, <属性2>, …])(如果关键字由多个属性构成,则必须使用第二种方法。)REFERENCES <表名>(<属性>)说明它参照了某个表的某些属性;或者在列出关系模式的所有属性后,增加一个或几个外部关键字说明,用FOREIGN KEY (<属性>) REFERENCES <表名> (<属性>)NOT NULL UNIQUE PRIMARY KEY FOREIGN KEY CHECK DEFAULTDATE: MM-DD-YYYY TIME: HH:MM:SSxCREATE TABLE Student( Sno CHAR(8) NOT NULL UNIQUE, Sname CHAR(20) UNIQUE, Ssex CHAR(2) NOT NULL, Sage SMALLINT, Sdept CHAR(20), PRIMARY KEY (Sno));CREATE TABLE Course( Cno CHAR(4) PRIMARY KEY, Cname CHAR(20), Cpno CHAR(4) REFERENCES Course(Cno), Ccredit SMALLINT);CREATE TABLE SC( Sno CHAR(8), Cno CHAR(4), Grade SMALLINT, PRIMARY KEY(Sno,Cno), FOREIGN KEY Sno REFERENCES Student(Sno), FOREIGN KEY Cno REFERENCES Course(Cno));xxxxxxxxxxALTER TABLE <表名> [ADD <列名><类型>[完整性约束]] [DROP <列名>[<完整性约束名>]] [ALTER COLUMN <列名> <类型>];Create table mydb1(id char(4) not null, sname char(32), sex nvarchar(4), deptid char(32));ALTER TABLE mydb1 /*增加名称必须取唯一值的约束条件*/ ADD Constraint UQ_name UNIQUE (name) /*添加表的主键约束*/ ADD Constraint PK_id primary key (id) /*添加表的外约束*/ ADD Constraint FK_deptid foreign key (deptid) references Dept (deptid) /*添加表的Check约束*/ ADD Constraint CK_sex Check (sex=‘男’or sex=‘女’) /*添加表的Default约束*/ ADD Constraint DF_sex Default (‘F’) for sex /*删除表*/ DROP TABLE <表名> [RESTRICT|CASCADE];xxxxxxxxxxCREATE [UNIQUE] [CLUSTERED|NOCLUSTERED] INDEX <索引名> ON <表名> (<列名> [<次序>] [, <列名> [<次序>] … ]);DROP INDEX <索引名> ON <表名>; CREATE UNIQUE INDEX U_idx_cname ON Course(Cname);CREATE UNIQUE INDEX SCno ON SC(Sno ASC, Cno DESC);DROP INDEX stusno ON student;= < > <= >= <> !=(NOT) BETWEEN AND(NOT) IN(NOT) LIKE,%代表任意长度字符串,_代表任意单个字符,ESCAPE ’/’可定义斜线用于转义符IS (NOT) NULLAND ORCOUNT SUM AVG MAX MINxxxxxxxxxxSELECT [ALL| DISTINCT] 属性1 AS 别名, 属性2 AS 别名…FROM 表名1, 表名2…[WHERE 条件表达式][GROUP BY 属性1, 属性2 …][HAVING 条件表达式][ORDER BY 属性1 [ASC|DESC], 属性2 …]/*查询计算机学院年龄在20岁以下的学生姓名*/SELECT SnameFROM StudentWHERE Sdept='计算机' AND Sage<20;/*查询以“DB_”开头,倒数第三个字符为i的课程的详细信息*/SELECT *FROM CourseWHERE Cname like ‘DB/_%i__’ escape ‘/’;/*查询选修了2门以上课程的学生学号*/SELECT SnoFROM SCGROUP BY SnoHAVING COUNT(Cno)>1/*查询学号在1-4之间至少选修了两门课程的学生学号及其选修的课程数并对课程数降序排序*/SELECT Sno,COUNT(Cno)FROM SCWHERE Sno BETWEEN '1' AND '4'GROUP BY SnoHAVING COUNT(Cno)>1ORDER BY COUNT(Cno) DESCxxxxxxxxxx/*等值与非等值连接查询*/[<表名1>.] <列名> <比较运算符> [<表名2>.]<列名>/*自身连接*//*外连接*/右外连接right join : =(*)左外连接left join :(*)=/*复合条件连接*/WHERE 子句中可以有多个连接条件/*集合运算*/UNION INTERSECT INTERSECTxxxxxxxxxx/*1.带有IN谓词的子查询(不相关子查询)*//*查询选修了数据库课程的学生学号和姓名*/SELECT Sno, SnameFROM StudentWHERE Sno IN( SELECT Sno FROM SC WHERE Cno IN ( SELECT Cno FROM Course WHERE Cname=‘数据库’)); /*查询选修了1号课程而没有选修2号课程的学生学号*/SELECT SnoFROM SCWHERE Cno='1'AND Sno NOT IN ( SELECT Sno FROM SC WHERE Cno='2');/*2.带有比较运算符的子查询(确切知道内查询返回单值时可用比较运算符)*//*找出每个学生超过他选修课程平均成绩的课程号*/SELECT Sno, CnoFROM SC xWHERE Grade >= (SELECT AVG(Grade) FROM SC y WHERE y.Sno=x.Sno); /*3.带有ANY或ALL的子查询(返回多值要用ANY或ALL谓词修饰符,同时使用比较运算符)*//*感觉回到了高考学的任意和存在,最大和最小问题,xswl*//*查询比计算机学院的学生年龄都小的学生姓名和年龄*/SELECT Sname, SageFROM Student 等价WHERE Sage < ALL WHERE Sage< (SELECT Sage (SELECT MIN(Sage) FROM Student FROM Student WHERE Sdept=‘计算机’); WHERE Sdept='计算机')EXISTS:代表存在量词 ,带有EXISTS的子查询不返回任何数据,只产生逻辑真值或逻辑假值。所有带IN谓词、比较运算符、ANY和ALL谓词的子查询都能用带EXISTS谓词的子查询等价替换。
IN与EXISTS等价对比
xxxxxxxxxx-- 查询没有被任何学生选修的课程的课程号;(课程号)SELECT 课程号FROM 课程WHERE 课程号 NOT IN ( SELECT 课程号 FROM 学习 );SELECT 课程号FROM 课程WHERE NOT EXISTS ( SELECT 课程号 FROM 学习 WHERE 课程.课程号 = 学习.课程号); -- 求没有选修课程“软件工程”的学生学号和姓名SELECT 学号, 姓名FROM 学生WHERE 学号 NOT IN ( SELECT 学号 FROM 学习,课程 WHERE 学习.课程号 = 课程.课程号 AND 课程名 = "软件工程");SELECT 学号, 姓名FROM 学生WHERE NOT EXISTS ( SELECT * FROM 学习,课程 WHERE 学生.学号=学习.学号 AND 学习.课程号=课程.课程号 AND 课程名="软件工程"); -- 错误写法!!SELECT DISTINCT 姓名, 学习.学号FROM 学习, 学生, 课程WHERE 学习.学号 = 学生.学号 AND 课程.课程号 = 学习.课程号 AND 课程.课程名 != '软件工程';▲除法的写法
xxxxxxxxxx/*查询选修了1号课而没有选修2号课的学生学号*/SELECT SnoFROM SC AWHERE Cno='1'AND NOT EXISTS ( SELECT * FROM SC B WHERE Cno=‘2’ AND A.Sno = B.Sno) /*查询至少选修了1号学生所选全部课程的学生编号*//*应该满足not exists (1号所选课程A-x号所选课程B) 为真*//*************STEP 1*************用Not Exists表示出A-B****** SELECT Cno FROM SC as A WHERE Sno='1' AND not Exists (SELECT Cno FROM SC as B WHERE Sno=‘x’ AND A.Cno= B.Cno)**************STEP 2*********Not Exists(A-B)的表示******WHERE Not Exists (SELECT * FROM SC as A WHERE Sno='1' AND not Exists (SELECT * FROM SC as B WHERE Sno=‘x’ AND A.Cno = B.Cno))**************STEP 3***************得到查询信息*************/SELECT distinct SnoFROM SCWHERE Not Exists (SELECT * FROM SC as A WHERE Sno='1' AND not Exists (SELECT * FROM SC as B WHERE SC.Sno = B.Sno AND A.Cno = B.Cno))xxxxxxxxxx/* 1.插入单个元组INSERTINTO <表名> [(<属性列1>[, <属性列2>…)]VALUES (<常量1>[, <常量2>]…); 2.插入子查询结果INSERTINTO <表名> [(<属性列1>[, <属性列2>…)]子查询 */INSERT INTO Student (Sno,Sname,Ssex,Sage,Sdept)VALUES(‘4’,’王磊’,’男’,19,’计算机’);/*对每一个系,求学生的平均年龄,并存入数据库*/CREATE TABLE Dept_age(Sdept CHAR(15),Avg_age SMALLINT);INSERT INTO Dept_age (Sdept, Avg_age)SELECT Sdept,AVG(Sage)FROM StudentGROUP BY Sdept;/*删除语句的一般格式DELETEFROM <表名>[ WHERE <条件> ];DELETE语句删除表中的数据,但表的定义仍然留在数据字典中*//*删除计算机学院所有学生的选课记录*/DELETE FROM SCWHERE Sno IN (SELECT Sno FROM Student WHERE Sdept =‘计算机’);/*修改操作语句的一般格式:UPDATE <表名>SET <列名>=<表达式> [, <列名>=<表达式>]…[WHERE <条件> ];*//*将计算机学院全体学生的成绩置零*/UPDATE SCSET Grade=0WHERE Sno IN (SELECT Sno FROM Student WHERE Sdept =‘计算机’);
xxxxxxxxxx/*建立视图组成视图的属性列名要么全部省略,要么全部指定在下列情况下必须列出视图的属性:1. 某个列不是单纯的属性名,而是聚集函数或表达式;2. 多表连接时,选出了几个同名列作为视图的字段;3. 需要在视图中为某个列启用新的名字。 CREATE VIEW < 视图名>[(<列名>[, <列名>]…)]AS <子查询>[WITH CHECK OPTION]; *//*建立计算机学院学生的视图*/CREATE VIEW CS_VIEWAS SELECT Sno,Sname,Sdept FROM Student WHERE Sdept=‘计算机’WITH CHECK OPTION/*建立计算机学院选修1号课程且成绩90以上的学生视图,包含学号、姓名和成绩*/CREATE VIEW CS_S1(Sno, Sname, Grade)AS SELECT Student.Sno, Sname, Grade FROM Student, SC WHERE Sdept=‘计算机’ AND Student.Sno=SC.Sno AND Cno=‘1’ AND Grade>=90/*查询视图:查询计算机学院的视图中年龄小于20岁的学生*/SELECT Sno,SageFROM CS_VIEWWHERE Sage<20/*更新视图:将CS_VIEW中学号为1号的学生姓名改为胡椒*/UPDATE CS_VIEWSET Sname=‘胡椒’WHERE Sno=‘1’/*删除视图*/DROP VIEW <视图名>[CASCADE]


例题
找出最高级范式和主码
- R(X, Y, Z), F={Y→Z, Y→X, X→YZ}
答案
- BCNF,主码:X,Y
依赖集等价:如果G+=F+,则称F与G等价,记为F≡G。(指他们的闭包相等)
等价充要条件:G+=F+充要条件是F包含于G+且G包含于F+。
最小依赖集:如果函数依赖集F满足下列条件,则称F为一个极小函数依赖集,也称最小依赖集或最小覆盖。
▲最小依赖集的算法:
定义:分解前的关系模式R和分解后的关系子模式集合ρ,是否保持相同的函数依赖
▲方法:
满足3NF的函数依赖保持分解算法:
满足3NF的函数依赖保持和无损连接的分解算法:先求出满足3NF的函数依赖保持的分解,看这个分解是否包含原关系模式的一个候选码,包含就是,不包含就在模式上加上去。
分析重点:信息要求(DB中需存储的数据)、处理要求(用户要求的处理功能、处理响应时间的要求)、安全性与完整性要求
调查需求步骤:
数据字典:关于数据库中数据的描述,元数据,而不是数据本身
E-R图转换为关系模式,实质是将实体和联系转为关系模式。
▲转换规则:
逻辑结构优化:确定范式级别、实施规范化管理
数据库保护功能:备份与恢复、并发控制、安全性控制、完整性控制
事务:是一个不可分割的操作序列,该操作序列要么全做,要么全不做,一个程序可以有多个事务。
事务特性(ACID):原子性(Atomicity,不可分割的工作单位)、一致性(Consistency, 事务提交后,数据库从一个一致性状态变到另一个一致性状态)、隔离性(Isolation,事务完成前,结果不能被其它事务引用)、持续性(Durability,事务执行成功,其对数据产生的效果永久有效)
事务执行五种状态:活动、部分提交、失败、中止

故障类型:事务故障、系统故障、介质故障、计算机病毒
基本原理:建立冗余
恢复技术:常用建立冗余方法包括数据转储、日志文件
数据转储
日志文件
故障恢复:
事务故障:反向扫描日志文件,将日志中更新前的数据写回到数据库中,直至事务的开始标志
系统故障:撤销故障发生时未完成的事务,重做已完成的事务
介质故障:DBA利用数据库副本和日志文件副本进行恢复
具有检查点的恢复策略(减少重做次数)

例题
设T1,T2是如下的2个事务 T1:A=A×B+2+D T2:B:=A×2+D,设A的初值为2,B的初值为4
(1)若这两个事务允许并发执行,讨论他们可能实施的调度,请一一列举并求每种调度的结果
(2)试给出一个可串行化调度,并给出执行结果
解答
R1(A) R1(B) R1(D) W1(A) R2(A) R2(D) W2(B) T1T2
R2(A) R2(D) W2(B) R1(A) R1(B) R1(D) W1(A) T2T1
R2(A) R2(D) R1(A) W2(B) R1(B) R1(D) W1(A)
排它锁(X锁,写锁):若事务T对数据对象A加上排它锁,则只允许T读取和修改A,不允许其他任何事务再对A加任何锁,直到T释放A上的X锁
共享锁(S锁,读锁):若事务T对数据对象A加上共享锁,则事务T可以读A但不能修改A,其他事务只能对A加S锁,而不能加X锁,直到T释放A上的S锁
封锁协议
| 封锁级别 | 加锁 | 放锁 |
|---|---|---|
| 一级 | 事务T在修改数据A之前必须对其加X锁 | 事务结束才释放X锁 |
| 二级 | 一级封锁协议加上事务T在读取数据A之前必须对其加S锁 | 读完后即可释放S锁 |
| 三级 | 一级封锁协议加上事务T在读取数据A之前必须对其加S锁 | 事务结束才释放S锁 |

PS:三级封锁协议防止可重复读,仅指解决了读不一致现象,不能解决幻影读现象。
两阶段协议(2PL):某一事务在对数据进行读、写之前,先要申请并获得对该数据的封锁。在释放一个封锁之后,事务不再申请和获得任何其它封锁。任何一个遵从2PL协议的调度都是冲突可串行化的(充分不必要条件)。
死锁:两个及以上事务相互等待释放锁,利用超时法或等待图发进行死锁检测。
活锁:某资源长期被一些事务封锁,其他事务得不到该资源,可采用先来先服务原则避免活锁。
xxxxxxxxxxGRANT <权限>[,<权限>]... [ON <对象类型> <对象名>] TO <用户>[,<用户>]... /*to public 授予所有用户*/ [WITH GRANT OPTION]; /*允许他再将此权限授予其他用户*//*把查询Student表权限授给用户U1*/ GRANT SELECT ON TABLE Student TO U1;/*把对Student表和Course表的全部权限授予用户U2和U3*/GRANT ALL PRIVILIGES ON TABLE Student, Course TO U2, U3;/*把查询Student表和修改学生学号的权限授给用户U4*/GRANT UPDATE(Sno), SELECT ON TABLE Student TO U4;REVOKE <权限>[,<权限>]... [ON <对象类型> <对象名>] FROM <用户>[,<用户>]...; /*from public*//*把用户U4修改学生学号的权限收回*/REVOKE UPDATE(Sno) ON TABLE Student FROM U4;/*角色是权限的集合 可以为一组具有相同权限的用户创建一个角色*/CREATE ROLE <角色名> GRANT <权限>[,<权限>]… ON <对象类型>对象名 TO <角色>[,<角色>]…/*视图机制*/CREATE VIEW CS_STUDENTASSELECT * FROM STDUENTWHERE SDEPT=‘计算机’;GRANT SELECT ON CS_STUDENT TO 王平;