考试题型:简答题(40分)、应用题(45分)、综合设计(15分)

题目特点:非标准答案,只要解答合理即可

1. 数据库的内部结构

数据库的内部结构从高到低分为三层:

外模式(用户模式/子模式)

是数据库用户能够看见和使用的局部数据的逻辑结构和特征的描述,是数据库用户的数据视图。一个数据库可以有多个外模式,不同用户看到的数据视图可以不同。

举例:教务系统中,学生只能看到自己的成绩(外模式A),而教师可以看到全班成绩(外模式B),管理员可以看到所有信息(外模式C)。

模式(逻辑模式)

是数据库中全体数据的逻辑结构和特征的描述,是所有用户的公共数据视图。一个数据库只有一个模式。

举例:教务系统的模式中定义了 Student(Sno, Sname, Ssex, Sage)、Course(Cno, Cname, Credit)、SC(Sno, Cno, Grade) 三张表及其关系。

内模式(存储模式)

是数据物理结构和存储方式的描述,是数据在数据库内部的组织方式。一个数据库只有一个内模式。

举例:Student 表使用 B+ 树索引按 Sno 排序存储,SC 表使用哈希索引加速按 Sno 的查询。

三级模式之间的两级映像:

  • 外模式/模式映像:保证了数据的逻辑独立性。当模式改变时,只需修改外模式/模式映像,外模式不变,应用程序不用修改。
  • 模式/内模式映像:保证了数据的物理独立性。当存储结构改变时,只需修改模式/内模式映像,模式不变,应用程序不用修改。

2. 数据库的三种完整性规则

实体完整性

主码的值不能为空(NOT NULL)且必须唯一。

举例:Student 表中 Sno 是主键,则 Sno 不能为 NULL,且不能有重复的 Sno。

参照完整性

外码的值要么等于被参照表中某个主码的值,要么为空。

举例:SC 表中的 Sno 是引用 Student 表的外键。SC 中的 Sno 值必须是 Student 表中已存在的 Sno,或者为 NULL(如果允许的话)。

用户定义完整性

针对某一具体应用的数据必须满足的语义要求,由用户根据具体需求定义。

举例:Student 表中 Sage(年龄)必须在 1545 之间;SC 表中 Grade(成绩)必须在 0100 之间。可以通过 CHECK 约束实现:

1
2
3
4
5
CREATE TABLE Student (
Sno CHAR(9) PRIMARY KEY,
Sname VARCHAR(20) NOT NULL,
Sage SMALLINT CHECK (Sage >= 15 AND Sage <= 45)
);

3. 并发问题与事务隔离级别

并发带来的问题

问题 说明 举例
丢失修改 两个事务同时修改同一数据,一个的修改被另一个覆盖 T1 读 A=100,T2 也读 A=100,T1 写 A=90,T2 写 A=80,T1 的修改丢失
不可重复读 事务内两次读取同一数据,结果不一致 T1 读 A=100,T2 修改 A=200 并提交,T1 再读 A=200,前后不一致
读脏数据 事务读到了另一个事务未提交的修改 T1 修改 A=100→200,T2 读 A=200,T1 回滚,T2 读到的 200 是脏数据
幻读 事务按条件读取后,另一个事务插入了符合条件的新数据 T1 查询有 3 条记录,T2 插入 1 条,T1 再查变成 4 条

四种隔离级别

隔离级别 脏读 不可重复读 幻读 说明
READ UNCOMMITTED(读未提交) ✓ 可能 ✓ 可能 ✓ 可能 最低级别,几乎不加锁,性能最高但数据一致性最差
READ COMMITTED(读已提交) ✗ 不会 ✓ 可能 ✓ 可能 只能读已提交的数据,Oracle、SQL Server 默认级别
REPEATABLE READ(可重复读) ✗ 不会 ✗ 不会 ✓ 可能 事务内多次读取同一数据结果一致,MySQL InnoDB 默认级别
SERIALIZABLE(串行化) ✗ 不会 ✗ 不会 ✗ 不会 最高级别,完全串行执行,一致性最好但并发性能最差

如何选择

  • 对数据一致性要求极高(如金融交易):选 SERIALIZABLE
  • 一般业务系统(大多数场景):选 READ COMMITTEDREPEATABLE READ
  • 对性能要求极高、可以容忍少量不一致(如数据分析):选 READ UNCOMMITTED

4. mysqldump 备份命令

备份整个数据库:

1
mysqldump -u root -p 数据库名 > backup.sql

备份数据库中的某几张表:

1
mysqldump -u root -p 数据库名 表名1 表名2 > backup.sql

备份多个数据库:

1
mysqldump -u root -p --databases db1 db2 > backup.sql

备份所有数据库:

1
mysqldump -u root -p --all-databases > backup_all.sql

还原数据库:

1
mysql -u root -p 数据库名 < backup.sql

常用参数:

  • --single-transaction:InnoDB 热备份,不锁表
  • --where="条件":只备份满足条件的数据
  • --no-data:只备份表结构不备份数据
  • --complete-insert:生成包含列名的 INSERT 语句

5. 关系代数

设关系 Student(Sno, Sname, Ssex, Sage, Sdept)

选择 σ(Selection)

从行的角度选取满足条件的元组。

含义:从 Student 表中选取年龄大于 20 的所有学生。

投影 π(Projection)

从列的角度选取若干属性列,自动去掉重复行。

含义:从 Student 表中只取 Sno 和 Sname 两列。

连接 ⋈(Join)

等值连接:选取两个关系中属性值相等的元组。

自然连接:在等值连接的基础上去掉重复的属性列。

含义:将 Student 和 SC 表按 Sno 相等连接,结果中 Sno 只保留一列。

除法 ÷(Division)

关系 R 除以关系 S 的结果,是 R 中满足”与 S 中所有元组都能匹配”的那些元组在某些属性上的投影。

设 R(A, B),S(B),R ÷ S 的结果是 R 中那些 A 值,使得该 A 对应的 B 值集合包含了 S 中所有 B 值。

举例:R 是选课表(Sno, Cno),S 是课程表(Cno)。R ÷ S 得到的是”选修了 S 中所有课程”的学生学号。


6. SQL 语句

(1)创建表(含主键、外键)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
CREATE TABLE Student (
Sno CHAR(9) PRIMARY KEY,
Sname VARCHAR(20) NOT NULL,
Ssex CHAR(2) DEFAULT '男',
Sage SMALLINT,
Sdept VARCHAR(20)
);

CREATE TABLE SC (
Sno CHAR(9),
Cno CHAR(4),
Grade SMALLINT,
PRIMARY KEY (Sno, Cno), -- 联合主键
FOREIGN KEY (Sno) REFERENCES Student(Sno), -- 外键
FOREIGN KEY (Cno) REFERENCES Course(Cno)
);

(2)为表增加 CHECK 约束

1
2
3
4
5
6
7
8
9
10
-- 建表时添加
CREATE TABLE SC (
Sno CHAR(9),
Cno CHAR(4),
Grade SMALLINT CHECK (Grade >= 0 AND Grade <= 100),
PRIMARY KEY (Sno, Cno)
);

-- 对已有表添加约束
ALTER TABLE SC ADD CONSTRAINT ck_grade CHECK (Grade >= 0 AND Grade <= 100);

(3)LIKE、_、% 的使用

  • %:匹配任意长度的字符串(包括空串)
  • _:匹配任意单个字符
1
2
3
4
5
6
7
8
9
10
11
-- 姓"张"的学生
SELECT * FROM Student WHERE Sname LIKE '张%';

-- 名字是两个字且姓"李"
SELECT * FROM Student WHERE Sname LIKE '李_';

-- 不姓"王"的学生(MySQL)
SELECT * FROM Student WHERE Sname NOT LIKE '王%';

-- 查询含有"数据"的课程名
SELECT * FROM Course WHERE Cname LIKE '%数据%';

(4)COUNT

1
2
3
4
5
6
7
8
-- 学生总数
SELECT COUNT(*) FROM Student;

-- 选了课的不同学生数(去重)
SELECT COUNT(DISTINCT Sno) FROM SC;

-- 每门课的选课人数
SELECT Cno, COUNT(Sno) AS 人数 FROM SC GROUP BY Cno;

(5)GROUP BY

1
2
3
4
5
6
7
8
9
10
-- 每个学生的平均成绩
SELECT Sno, AVG(Grade) AS 平均分
FROM SC
GROUP BY Sno;

-- 查询平均成绩大于 80 的学生
SELECT Sno, AVG(Grade) AS 平均分
FROM SC
GROUP BY Sno
HAVING AVG(Grade) > 80;

注意:WHERE 子句在分组前过滤,HAVING 子句在分组后过滤。

(6)带子查询的 UPDATE 和 DELETE

1
2
3
4
5
6
7
8
-- 将计算机系所有学生的成绩置零
UPDATE SC
SET Grade = 0
WHERE Sno IN (SELECT Sno FROM Student WHERE Sdept = '计算机');

-- 删除"张三"同学的选课记录
DELETE FROM SC
WHERE Sno = (SELECT Sno FROM Student WHERE Sname = '张三');

(7)自身连接、嵌套查询、NOT EXISTS 实现全部

自身连接——查询每门课的先修课:

1
2
3
SELECT a.Cno, b.Cno AS 先修课号
FROM Course a, Course b
WHERE a.Cpno = b.Cno;

嵌套查询——查询选修了”数据库”课程的学生姓名:

1
2
3
4
5
6
7
SELECT Sname FROM Student
WHERE Sno IN (
SELECT Sno FROM SC
WHERE Cno = (
SELECT Cno FROM Course WHERE Cname = '数据库'
)
);

NOT EXISTS 实现”全部”(除法)——查询选修了全部课程的学生:

1
2
3
4
5
6
7
8
SELECT Sname FROM Student
WHERE NOT EXISTS (
SELECT * FROM Course
WHERE NOT EXISTS (
SELECT * FROM SC
WHERE SC.Sno = Student.Sno AND SC.Cno = Course.Cno
)
);

解读:双重 NOT EXISTS = “不存在一门课,该学生没有选修” = “该学生选修了所有课”。


7. 函数依赖与范式

部分依赖 vs 完全依赖

设关系 R(A, B, C),主键为(A, B):

  • 完全依赖:C 完全依赖于整个主键(A, B),即必须同时知道 A 和 B 才能确定 C。
  • 部分依赖:C 只依赖于主键的一部分,比如 C 只依赖于 A,则 C 部分依赖于主键。

举例:SC(Sno, Cno, Grade, Sname) 中,主键是(Sno, Cno)。Grade 完全依赖于(Sno, Cno),但 Sname 只依赖于 Sno,所以 Sname 对主键是部分依赖。

范式级别

范式 要求 消除的问题
1NF 属性不可再分
2NF 在 1NF 基础上,消除非主属性对主键的部分依赖 部分依赖
3NF 在 2NF 基础上,消除非主属性对主键的传递依赖 传递依赖
BCNF 在 3NF 基础上,消除主属性对主键的部分和传递依赖 主属性的部分/传递依赖

2NF 分解算法

将部分依赖的属性拆分到新表中。

原表:SC(Sno, Cno, Grade, Sname),主键(Sno, Cno),Sname 部分依赖于 Sno。

分解为:

  • **SG(Sno, Sname)**——Sname 完全依赖于 Sno
  • **SC(Sno, Cno, Grade)**——Grade 完全依赖于(Sno, Cno)

范式级别判定

判断步骤:

  1. 找出所有函数依赖(包括候选键推导出的)
  2. 找出主键和候选键
  3. 逐级检查是否满足各范式条件

举例:R(A, B, C, D),函数依赖:A→B, B→C, A→D。
候选键:A(因为 A→B, B→C 所以 A→C,加上 A→D,A 能决定所有属性)。
检查 2NF:所有非主属性(B, C, D)都完全依赖于 A(A 是单属性主键,不可能有部分依赖),满足 2NF。
检查 3NF:B→C,C 传递依赖于 A(A→B→C),不满足 3NF。
结论:该关系属于 2NF,不属于 3NF。

无损连接判定

分解为 R1 和 R2 无损连接的充要条件:

即:两个子模式的交集能函数依赖推出其中某一个子模式的差集。

举例:R(A, B, C),F={A→B}。分解为 R1(A, B) 和 R2(A, C)。
R1 ∩ R2 = A,R1 - R2 = B,A→B 成立,所以该分解是无损连接。

保持依赖的判定

分解后的各子关系上的函数依赖集的并集,与原函数依赖集 F 等价(即能推出相同的依赖),则保持依赖。

简单判断:F 中的每个函数依赖的左边和右边所有属性是否在同一个子关系中出现。如果是,则保持依赖。


8. ER 图与关系模式转换

ER 图基本元素

  • 实体(矩形):如 Student、Course
  • 属性(椭圆):如 Sname、Sage,用无向边连到实体
  • 联系(菱形):如”选修”,用无向边连到相关实体

联系类型

类型 说明 举例
1:1 一对一 班级—班长
1:n 一对多 系—学生
m:n 多对多 学生—课程

ER 图转关系模式规则

1:1 联系

可以将联系合并到任意一方实体的关系模式中,也可以单独建表。

例:班级(班号, 班名) 和 班长(学号, 姓名),1:1 联系。
合并方案:班级(班号, 班名, 班长学号)——在班级表中加外键。

1:n 联系

将联系合并到 n 端实体的关系模式中,在 n 端加外键。

例:系(系号, 系名) 和 学生(学号, 姓名, 系号)——在学生表中加系号外键。

m:n 联系

必须为联系单独建立一个关系模式,主键为两端实体主键的组合。

例:学生(Sno, Sname) 和 课程(Cno, Cname),m:n 联系”选修”有属性 Grade。
转换为三个关系模式:

  • Student(Sno, Sname)
  • Course(Cno, Cname)
  • SC(Sno, Cno, Grade)——联合主键,两个外键