软件设计师考点详解:数据库技术(关系理论与SQL应用)

数据库技术是软件设计师考试的核心章节之一,约占上午题的12%,同时也是下午应用题的必考内容。这部分内容理论与实践并重,既需要理解关系理论的数学基础,又要掌握SQL的实际应用。本文将系统梳理数据库技术的核心知识点。

一、数据库系统基本概念

数据库系统组成

四个组成部分

  • 数据库(DB):存储数据的集合
  • 数据库管理系统(DBMS):管理数据库的软件
  • 应用程序:访问数据库的程序
  • 数据库管理员(DBA):负责数据库管理的人员

三级模式结构

  • 外模式(用户模式):用户看到的数据视图
  • 概念模式(逻辑模式):全局数据逻辑结构
  • 内模式(存储模式):数据的物理存储结构

两级映像

  • 外模式/概念模式映像:保证逻辑独立性
  • 概念模式/内模式映像:保证物理独立性

数据模型分类

层次模型

  • 树形结构,一对多关系
  • 优点:查询效率高
  • 缺点:表示复杂关系困难

网状模型

  • 网状结构,多对多关系
  • 优点:表示复杂关系能力强
  • 缺点:结构复杂,用户使用困难

关系模型

  • 二维表格结构
  • 优点:结构简单,理论基础完善
  • 缺点:连接操作开销大
  • 当前主流模型

面向对象模型

  • 结合面向对象和关系模型
  • 支持复杂数据类型和继承

二、关系数据库理论

关系的基本概念

关系(Relation):二维表
元组(Tuple):表中的一行
属性(Attribute):表中的一列
域(Domain):属性的取值范围
候选键(Candidate Key):能唯一标识元组的最小属性集
主键(Primary Key):被选作主键的候选键
外键(Foreign Key):引用其他关系主键的属性

关系代数

基本运算

选择(Selection) σ:

  • 从关系中选择满足条件的元组
  • 示例:σ_年龄>20(学生)

投影(Projection) π:

  • 从关系中选择指定的属性列
  • 示例:π_姓名,年龄(学生)

并(Union) ∪:

  • 两个关系的元组合并(要求关系兼容)
  • 示例:R ∪ S

差(Difference) -:

  • 属于R但不属于S的元组
  • 示例:R - S

笛卡尔积(Cartesian Product) ×:

  • 两个关系的所有元组组合
  • 示例:R × S

连接(Join) ⋈:

  • 笛卡尔积 + 选择条件
  • 等值连接:连接条件为等式
  • 自然连接:相同属性名的等值连接,去除重复列

除(Division) ÷:

  • 找出在R中与S所有元组都有关联的元组
  • 应用场景:查询选修了所有课程的学生

函数依赖

定义

  • X → Y 表示X函数决定Y
  • 对于关系R的任意两个元组,如果X值相同,则Y值也相同

Armstrong公理系统

  • 自反律:若Y⊆X,则X→Y
  • 增广律:若X→Y,则XZ→YZ
  • 传递律:若X→Y,Y→Z,则X→Z

推导规则

  • 合并规则:X→Y,X→Z ⇒ X→YZ
  • 分解规则:X→YZ ⇒ X→Y,X→Z
  • 伪传递规则:X→Y,WY→Z ⇒ WX→Z

闭包计算

  • X⁺ 表示X能函数决定的所有属性集合
  • 算法:初始X⁺=X,反复应用函数依赖直到不再扩大

最小覆盖

  • 每个函数依赖右边都是单属性
  • 没有多余的属性在左边
  • 没有多余的函数依赖

三、数据库范式理论

第一范式(1NF)

定义

  • 关系中的每个属性都是不可再分的原子值
  • 消除重复组和多值属性

判断方法

  • 检查是否存在复合属性或重复组
  • 确保每个单元格只包含单个值

第二范式(2NF)

定义

  • 满足1NF
  • 消除非主属性对候选键的部分函数依赖

部分依赖

  • 在组合键的情况下,非主属性只依赖于候选键的一部分

规范化方法

  • 将存在部分依赖的属性分离到新关系中

示例

1
2
3
4
订单详情(订单ID, 商品ID, 商品名称, 商品价格, 数量)
候选键:(订单ID, 商品ID)
问题:商品名称、商品价格只依赖于商品ID(候选键的一部分)
解决方案:拆分为 订单详情(订单ID, 商品ID, 数量) 和 商品(商品ID, 商品名称, 商品价格)

第三范式(3NF)

定义

  • 满足2NF
  • 消除非主属性对候选键的传递函数依赖

传递依赖

  • X → Y,Y → Z,且Y不→X,则X → Z是传递依赖

规范化方法

  • 将存在传递依赖的属性分离到新关系中

示例

1
2
3
4
学生(学号, 姓名, 系名, 系主任)
函数依赖:学号→系名,系名→系主任
问题:系主任传递依赖于学号
解决方案:拆分为 学生(学号, 姓名, 系名) 和 系(系名, 系主任)

BCNF(Boyce-Codd范式)

定义

  • 对于关系中的每个非平凡函数依赖X→Y,X都是超键

与3NF的区别

  • 3NF允许主属性对候选键的传递依赖
  • BCNF不允许任何非超键决定其他属性

示例

1
2
3
4
5
6
授课(教师, 课程, 教室)
假设:每个教师只教一门课程,每门课程只在一个教室上
函数依赖:教师→课程,课程→教室
候选键:(教师, 教室) 或 (课程, 教室)
问题:教师→课程中,教师不是超键
解决方案:拆分为 授课1(教师, 课程) 和 授课2(课程, 教室)

范式关系总结

范式 消除的问题 依赖要求
1NF 非原子属性 -
2NF 部分依赖 非主属性完全依赖候选键
3NF 传递依赖 非主属性直接依赖候选键
BCNF 主属性依赖 所有决定因素都是超键

四、SQL语言基础

数据定义语言(DDL)

创建表

1
2
3
4
5
6
7
CREATE TABLE 学生 (
学号 CHAR(10) PRIMARY KEY,
姓名 VARCHAR(20) NOT NULL,
年龄 INT CHECK(年龄 BETWEEN 16 AND 30),
系名 VARCHAR(20),
FOREIGN KEY (系名) REFERENCES 系(系名)
);

修改表

1
2
3
4
5
6
7
8
-- 添加列
ALTER TABLE 学生 ADD 邮箱 VARCHAR(50);

-- 删除列
ALTER TABLE 学生 DROP COLUMN 邮箱;

-- 修改列
ALTER TABLE 学生 MODIFY 年龄 SMALLINT;

删除表

1
2
DROP TABLE 学生;  -- 删除表及数据
TRUNCATE TABLE 学生; -- 只删除数据,保留表结构

数据操纵语言(DML)

插入数据

1
2
3
4
5
-- 插入完整行
INSERT INTO 学生 VALUES ('2021001', '张三', 20, '计算机系');

-- 插入指定列
INSERT INTO 学生(学号, 姓名, 系名) VALUES ('2021002', '李四', '数学系');

更新数据

1
2
3
4
5
-- 更新所有记录
UPDATE 学生 SET 年龄 = 年龄 + 1;

-- 条件更新
UPDATE 学生 SET 年龄 = 21 WHERE 姓名 = '张三';

删除数据

1
2
3
4
5
-- 删除所有记录
DELETE FROM 学生;

-- 条件删除
DELETE FROM 学生 WHERE 年龄 < 18;

数据查询语言(DQL)

基本查询

1
2
3
4
5
6
7
8
9
10
11
-- 查询所有列
SELECT * FROM 学生;

-- 查询指定列
SELECT 姓名, 年龄 FROM 学生;

-- 条件查询
SELECT * FROM 学生 WHERE 年龄 > 20;

-- 排序
SELECT * FROM 学生 ORDER BY 年龄 DESC, 姓名 ASC;

聚合函数

1
SELECT COUNT(*), AVG(年龄), MAX(年龄), MIN(年龄) FROM 学生;

分组查询

1
2
3
4
5
-- 按系分组统计
SELECT 系名, COUNT(*) AS 人数, AVG(年龄) AS 平均年龄
FROM 学生
GROUP BY 系名
HAVING COUNT(*) > 10; -- 分组后筛选

连接查询

1
2
3
4
5
6
7
8
-- 内连接
SELECT 学生.姓名, 课程.课程名, 选课.成绩
FROM 学生 JOIN 选课 ON 学生.学号 = 选课.学号
JOIN 课程 ON 选课.课程号 = 课程.课程号;

-- 左外连接
SELECT 学生.姓名, 选课.课程号
FROM 学生 LEFT JOIN 选课 ON 学生.学号 = 选课.学号;

子查询

1
2
3
4
5
6
7
-- WHERE子查询
SELECT 姓名 FROM 学生
WHERE 年龄 > (SELECT AVG(年龄) FROM 学生);

-- EXISTS子查询
SELECT 姓名 FROM 学生 s
WHERE EXISTS (SELECT * FROM 选课 sc WHERE sc.学号 = s.学号);

数据控制语言(DCL)

权限管理

1
2
3
4
5
-- 授权
GRANT SELECT, INSERT ON 学生 TO 用户名;

-- 收权
REVOKE SELECT ON 学生 FROM 用户名;

事务控制

1
2
3
4
BEGIN TRANSACTION;
UPDATE 账户 SET 余额 = 余额 - 100 WHERE 账号 = 'A';
UPDATE 账户 SET 余额 = 余额 + 100 WHERE 账号 = 'B';
COMMIT; -- 或 ROLLBACK;

五、数据库设计方法

ER模型设计

ER图基本元素

  • 实体(Entity):矩形表示
  • 属性(Attribute):椭圆表示
  • 联系(Relationship):菱形表示
  • 主键:下划线标注

联系类型

  • 一对一(1:1):如部门与经理
  • 一对多(1:N):如班级与学生
  • 多对多(M:N):如学生与课程

ER图转换为关系模式

实体转换

  • 每个实体转换为一个关系
  • 实体的属性成为关系的属性
  • 实体的键成为关系的主键

联系转换

  • 1:1联系:可合并到任一实体关系中
  • 1:N联系:在N端关系中添加1端的主键作为外键
  • M:N联系:创建新的关系,包含两端的主键

示例转换

1
2
3
学生(学号, 姓名, 年龄)
课程(课程号, 课程名, 学分)
选课(学号, 课程号, 成绩) -- M:N联系转换

数据库设计步骤

需求分析

  • 收集用户需求
  • 确定数据范围和处理要求
  • 输出数据字典和数据流图

概念设计

  • 设计ER模型
  • 验证概念模型的正确性
  • 输出ER图

逻辑设计

  • ER图转换为关系模式
  • 规范化处理
  • 优化关系模式

物理设计

  • 选择存储结构
  • 创建索引
  • 确定存取方法

实施与维护

  • 创建数据库
  • 数据加载
  • 运行维护

六、常考题型与解题技巧

范式判断题

典型问题

  • 判断关系属于哪个范式
  • 分析存在的函数依赖问题
  • 进行范式分解

解题技巧

  • 逐步检查:1NF → 2NF → 3NF → BCNF
  • 找出所有候选键
  • 分析函数依赖,识别部分依赖和传递依赖
  • 按照规范化步骤进行分解

ER图设计题

典型问题

  • 根据需求描述绘制ER图
  • 将ER图转换为关系模式
  • 分析ER图的合理性

解题技巧

  • 准确识别实体、属性和联系
  • 注意联系的基数约束(1:1, 1:N, M:N)
  • 转换时注意主键和外键的设置
  • 验证转换后的关系模式是否满足范式要求

SQL编写题

典型问题

  • 编写复杂查询语句
  • 使用子查询和连接
  • 聚合函数和分组查询

解题技巧

  • 先分析需要哪些表,确定连接方式
  • 确定查询条件和筛选逻辑
  • 考虑是否需要分组和聚合
  • 注意NULL值的处理

关系代数题

典型问题

  • 用关系代数表达查询
  • 计算关系代数表达式的结果

解题技巧

  • 熟悉基本运算符的含义和用法
  • 按照运算优先级逐步计算
  • 注意自然连接会去除重复列

七、学习建议

重点掌握内容

  1. 函数依赖:理解各种依赖类型和Armstrong公理
  2. 范式理论:掌握各范式的定义和规范化方法
  3. SQL语言:熟练编写各种类型的SQL语句
  4. ER模型:能够准确设计ER图并转换为关系模式
  5. 关系代数:理解基本运算和表达式构造

学习方法

  • 动手实践:在数据库系统中实际创建表和执行SQL
  • 画图辅助:通过ER图和函数依赖图理解概念
  • 对比记忆:各范式之间的区别和联系
  • 真题训练:通过历年真题熟悉考试题型

经验分享:数据库这部分内容既有理论深度又有实践价值。建议在理解理论的同时,多动手练习SQL编写和数据库设计。可以使用MySQL、PostgreSQL等免费数据库系统进行实践。


下一篇将讲解网络与信息安全技术,包括协议栈、加密算法和安全机制等内容。