📖 第三章 · 数据库系统

数据库系统

涵盖关系代数、键与完整性、范式理论、事务ACID、并发控制、SQL优化、NoSQL选型及数据库设计全过程。本章约占7%-13%,案例分析中数据库设计也是重点。

8知识模块
7%-13%分值占比
40+核心知识点
★★★★重要程度
📊

关系代数

🔢基本运算

运算符号说明类型
选择(Selection)σ按条件筛选行(元组),结果结构与原关系相同一元
投影(Projection)π选择指定列(属性),自动去重一元
并(Union)两个关系的元组合并,要求同构(属性相同)集合
差(Difference)-在R中但不在S中的元组,要求同构集合
笛卡尔积×R的每个元组与S的每个元组组合,结果列数=两表列数之和集合

🔗连接运算

类型说明示例
θ连接按任意条件连接(>、<、=、≥等)R ⋈(A>B) S
等值连接θ连接的特例,条件为"="R ⋈(A=B) S
自然连接等值连接+去重(相同属性名自动匹配,结果中相同属性只保留一列)R ⋈ S(自动匹配同名列)
外连接保留未匹配元组。左外连接(保留左表)、右外连接(保留右表)、全外连接(都保留)R ⟕ S / R ⟖ S / R ⟗ S
半连接R中能与S匹配的元组,结果只包含R的属性R ⋉ S

除运算

定义:R ÷ S 返回R中那些在S的所有元组上都有对应组合的元组。即"找出R中包含了S中所有情况的X值"
理解口诀:"谁全有"——R÷S的结果是:在R中与S的每一个元组都有配对的那些属性值
运算优先级:括号 > 投影/选择 > 连接/除 > 并/差 > 笛卡尔积。实际做题时从左到右,括号优先
⚠️
自然连接 vs 等值连接:自然连接自动匹配同名列且结果中去重(同名列只出现一次);等值连接需要显式指定条件,结果中包含两个匹配列。考试常给两个关系表,要求计算自然连接后的元组数量和列数。
🔑

键与完整性

🗝️键的层次关系

超键(Super Key):能唯一标识元组的属性集(可能包含多余属性)。范围最大
候选键(Candidate Key):最小超键,不含多余属性。一个关系可以有多个候选键
主键(Primary Key):从候选键中选定一个作为主键。唯一且非空
外键(Foreign Key):引用另一关系主键的属性。用于建立表间联系,实现参照完整性
主属性:包含在任一候选键中的属性。非主属性则不包含在任何候选键中

🛡️完整性约束

类型含义规则
实体完整性主键约束主键属性不能为空(NOT NULL)且值唯一
参照完整性外键约束外键要么为空,要么引用被参照表中存在的主键值
用户定义完整性业务规则约束由用户定义的约束条件,如CHECK、UNIQUE、DEFAULT等
💡
包含关系:候选键 ⊂ 超键(候选键是最小超键);主键 ∈ 候选键(主键是候选键之一)。一个表只能有一个主键,但可以有多个候选键。
键的层次关系图
超键(Super Key)— 能唯一标识元组的最大集合
候选键(Candidate Key)— 最小超键,不含多余属性
主键(Primary Key)— 从候选键中选定的一个
外键(Foreign Key)— 引用另一关系的主键
包含关系:超键 ⊃ 候选键 ⊃ 主键
🔄

函数依赖与范式

📐函数依赖

完全函数依赖:X→Y,且X的任何真子集都不能决定Y。记作 X →(f) Y
部分函数依赖:X→Y,但X的某个真子集也能决定Y
传递函数依赖:X→Y,Y→Z,且Y不→X,则X→Z是传递依赖
多值依赖:X→→Y,X的值决定Y的一组值,与Z无关

📊范式判断流程

范式判断条件消除的问题
1NF所有属性都是原子的(不可再分)属性的原子性
2NF在1NF基础上,非主属性完全函数依赖于候选键(无部分依赖)部分函数依赖
3NF在2NF基础上,非主属性不传递依赖于候选键(无传递依赖)传递函数依赖
BCNF在3NF基础上,每个决定因素都包含候选键主属性对候选键的部分/传递依赖

反范式化

定义:为提高查询性能,有意引入冗余,降低范式级别
适用场景:读多写少、查询涉及多表JOIN、数据仓库/OLAP场景
代价:空间换时间,需要额外维护数据一致性
⚠️
范式判断步骤:①找候选键 ②检查是否有非主属性对候选键的部分依赖→若有则不到2NF ③检查是否有非主属性的传递依赖→若有则不到3NF ④检查是否所有决定因素都包含候选键→若有不包含则不到BCNF。BCNF是3NF的增强,BCNF一定满足3NF,反之不然。
范式升级流程图
1NF
属性原子
2NF
消除部分依赖
3NF
消除传递依赖
BCNF
决定因素含候选键
升级方向:消除冗余 → 消除异常|BCNF ⊆ 3NF ⊆ 2NF ⊆ 1NF
💎

事务与ACID

🔷ACID四特性

原子性(Atomicity):事务是原子操作单元,要么全部执行成功,要么全部不执行。由Undo Log实现
一致性(Consistency):事务执行前后数据库保持一致状态(约束不被破坏)。是最终目标
隔离性(Isolation):并发事务之间互不干扰。由锁机制和MVCC实现
持久性(Durability):事务一旦提交,结果永久保存。由Redo Log实现

🔀隔离级别与并发问题

隔离级别脏读不可重复读幻读性能
读未提交(Read Uncommitted)可能可能可能最高
读已提交(Read Committed)防止可能可能
可重复读(Repeatable Read)防止防止可能(MySQL InnoDB防止)
串行化(Serializable)防止防止防止最低

📖并发问题详解

脏读:读取了另一个事务未提交的数据。对方回滚后读到的是脏数据
不可重复读:同一事务内两次读取同一行数据,结果不一致(其他事务修改并提交)
幻读:同一事务内两次执行相同查询,返回的行数不同(其他事务插入/删除)
💡
记忆口诀:"脏不可幻"——脏读最容易发生(读未提交),幻读最难防(需串行化)。MySQL InnoDB默认隔离级别是"可重复读",通过MVCC解决了大部分幻读问题。Oracle默认是"读已提交"。
隔离级别与并发问题关系图
隔离级别脏读不可重复读幻读性能
读未提交✗ 可能✗ 可能✗ 可能最高
读已提交✓ 防止✗ 可能✗ 可能
可重复读✓ 防止✓ 防止△ MySQL防
串行化✓ 防止✓ 防止✓ 防止最低
一致性 ↑ —— 并发性能 ↓
🔒

并发控制

🔐封锁协议

锁类型符号兼容性说明
共享锁(读锁)S锁S与S兼容,S与X互斥允许多个事务同时读,但不允许写
排他锁(写锁)X锁X与任何锁互斥只允许一个事务读写,排斥其他所有锁

📋三级封锁协议

级别读操作写操作解决的问题
一级封锁协议不强制加锁修改前加X锁,事务结束释放防止丢失修改
二级封锁协议读前加S锁,读完立即释放同一级+防止脏读
三级封锁协议读前加S锁,事务结束释放同一级+防止不可重复读

🔑两阶段锁协议(2PL)

扩展阶段(Growing):只能获取锁,不能释放锁
收缩阶段(Shrinking):只能释放锁,不能获取锁
保证:2PL保证可串行化调度,但不保证无死锁

📑MVCC(多版本并发控制)

核心思想:数据有多份历史版本,读操作读取快照版本,写操作创建新版本
实现方式:每行数据记录创建版本号和删除版本号。读操作选择合适版本的数据
优点:读不加锁,读写不冲突,大大提高并发性能
典型应用:MySQL InnoDB、PostgreSQL
⚠️
易混淆:一级→二级→三级封锁协议,级别越高加锁范围越大(读锁从"不强制"到"读完即放"到"事务结束放")。解决的问题也是递进的:丢失修改→脏读→不可重复读。注意"丢失修改"是两个事务同时修改同一数据,后一个覆盖了前一个。

SQL优化

🌳索引类型与B+树

B+树索引:最常用的索引结构。非叶子节点只存索引,叶子节点存数据且有序链表连接。范围查询高效
哈希索引:等值查询O(1),不支持范围查询和排序
聚簇索引:数据与索引存储在一起(InnoDB主键),一个表只能有一个
非聚簇索引:索引与数据分开存储,叶子节点存主键值(回表查询)
覆盖索引:查询的列全部在索引中,无需回表
复合索引:多列联合索引。遵循最左前缀原则(MySQL)

📝查询优化原则

避免 SELECT *:只查询需要的列,减少网络传输和内存消耗
合理使用索引:WHERE条件列加索引;避免在索引列上使用函数/表达式(会导致索引失效)
减少子查询:用JOIN替代子查询,优化器更容易优化
使用 EXPLAIN:分析SQL执行计划,查看是否使用了索引、扫描类型
批量操作:批量INSERT比逐条INSERT快很多
分页优化:大数据量LIMIT分页时,用延迟关联(先通过索引找到主键再回表)

📊分库分表策略

策略方式适用场景挑战
水平拆分按行拆分(同一表结构,不同数据)数据量大、单表行数过多跨分片查询、JOIN困难
垂直拆分按列拆分(按业务模块分表)表字段多、访问频率差异大跨表JOIN、事务管理
读写分离主库写+从库读读多写少场景主从延迟、数据一致性

⚠️缓存三大问题

问题描述解决方案
缓存穿透查询不存在的数据(缓存和数据库都没有)布隆过滤器、缓存空值(短过期时间)
缓存击穿热点Key集中过期,大量请求打到数据库互斥锁(SETNX)、永不过期(逻辑过期)
缓存雪崩大量Key同时过期或缓存服务宕机随机过期时间、多级缓存、限流降级
💡
索引失效场景:①索引列参与计算 ②索引列使用函数 ③LIKE '%xxx'(前导通配符) ④OR条件中有列无索引 ⑤复合索引不满足最左前缀 ⑤类型转换(字符串没加引号)
🗂️

NoSQL数据库

🗃️四大NoSQL类型

类型代表产品数据模型优势典型场景
键值存储Redis、MemcachedKey-Value对极高的读写性能缓存、会话、计数器
文档存储MongoDB、CouchDBJSON/BSON文档灵活Schema、嵌套查询内容管理、日志存储
列族存储HBase、Cassandra宽列(动态列)海量写入、稀疏数据高效时序数据、大数据分析
图数据库Neo4j、JanusGraph节点+边(图结构)关系查询高效社交网络、知识图谱、推荐

⚖️CAP定理与BASE理论

CAP定理:分布式系统最多同时满足三个中的两个——一致性(C)、可用性(A)、分区容错性(P)。网络分区必然存在,所以只能在C和A间选择
CP型:牺牲可用性保一致性。如Zookeeper、HBase、etcd
AP型:牺牲一致性保可用性。如Cassandra、DynamoDB、Eureka
BASE理论:BA(基本可用)+ S(软状态)+ E(最终一致性)。是AP的延伸,适合大规模分布式系统
⚠️
选型对比:关系型DB强调ACID、严格一致性、结构化数据;NoSQL强调BASE、最终一致性、灵活Schema、水平扩展。实际架构中常结合使用——关系型做核心交易,NoSQL做缓存/分析/日志。
🎨

数据库设计过程

🔄设计四阶段

需求分析阶段:收集数据需求、处理需求。输出:数据字典(DD)、数据流图(DFD)。明确"需要什么数据"
概念结构设计:E-R模型(实体-联系图)。实体(矩形)、属性(椭圆)、联系(菱形,标注1:1/1:N/M:N)。独立于具体DBMS
逻辑结构设计:E-R图→关系模式。应用范式理论规范化。确定表结构、键、约束。与具体DBMS相关
物理结构设计:选择存储结构(堆/有序/聚簇)、存取方法(索引)、确定文件组织方式。关注性能优化

🔄ER图转关系模式规则

联系类型转换规则示例
1:1可以合并到任一端的关系中,将另一端主键+联系属性作为外键加入部门-经理(1:1),合并到部门表加经理ID
1:N在N端加入1端的主键作为外键,联系的属性也放在N端部门-员工(1:N),员工表加部门ID
M:N必须转换为独立的关系,包含两端主键+联系属性,主键为两端主键组合学生-课程(M:N),独立选课表(学号,课程号,成绩)
多元联系三个及以上实体间的联系,转为独立关系,包含各实体主键供应商-项目-零件(M:N:P)

📊数据库设计注意事项

命名规范:表名用名词复数、字段名清晰明确、避免保留字
数据类型选择:能用小类型就不用大类型(TINYINT vs INT),字符串用VARCHAR而非CHAR(可变长度)
主键策略:自增ID(简单有序)vs UUID(分布式友好但无序)vs Snowflake(分布式有序)
审计字段:created_at、updated_at、deleted_at(软删除)
⚠️
案例分析常考:给出ER图,要求转换为关系模式,指出主键和外键。M:N联系必须单独建表!1:N联系在外键放在N端。注意检查是否满足3NF,是否需要拆分。
📝

章节练习

📝 本章练习题正在加载...