教材从“现实世界→信息世界→数据世界”的抽象路径切入,强调概念模型(E-R图)是连接业务与数据库的桥梁。例如:在“学生选课”场景中,“选课”本身不是实体而是关联关系,应表示为三元关系而非二元。
SC_T(学号, 课程号, 教师号, 成绩)
错误建模
学生(学号, 姓名) —— 选课(学号, 课程号) —— 课程(课程号, 教师号)
→ 丢失了“某教师教某课程”的直接约束,导致无法查询“张老师教哪几门课”(需多表JOIN)
教材重点解析“为什么需要分解”:以“学生信息表”包含姓名、学院、专业、课程、成绩为例,若直接存储会导致“插入异常”(新生未选课无法入库)、“删除异常”(退课导致学生信息丢失)、“更新异常”(修改专业需改多行)。
- 1NF:属性不可再分(如“地址”拆为省/市/区/街道)
- 2NF:消除部分函数依赖(主键为复合键时)
- 3NF:消除传递依赖(如学号→学院→系主任)
- BCNF:所有决定因素都是候选码(更严格,适用于高一致性场景)
教材特别强调:“范式设计服务于业务需求”。在OLTP系统中,3NF可减少冗余、保障一致性;但在OLAP场景下,为加速查询常反范式化(如宽表设计),甚至存储冗余字段(如订单表中冗余“用户姓名”)。
例如:电商大促时,若实时JOIN用户表获取姓名,会导致锁竞争加剧、响应延迟升高;此时提前写入冗余字段,可将查询从3表JOIN降为单表,TPS提升300%。
教材通过200+真实错误案例总结以下高危写法:
- ❌
SELECT FROM users WHERE name LIKE '%张%'→ 全表扫描! - ✅ 改为:
SELECT id, name FROM users WHERE name = '张三'(精确匹配)或建立name全文索引 - ❌
UPDATE orders SET status = 'paid' WHERE user_id IN (SELECT id FROM users WHERE level = 'vip')→ 子查询未优化易超时 - ✅ 改为:
UPDATE orders o INNER JOIN users u ON o.user_id = u.id SET o.status = 'paid' WHERE u.level = 'vip'
? 教材提示:执行EXPLAIN是SQL优化的第一步,关注type列(ALL=全表扫描,range=范围扫描,ref=索引匹配)。
教材提供“四步查询法”模板,适用于90%复杂场景:
2️⃣ 确定数据来源表(FROM ...)
3️⃣ 确定连接关系(JOIN ... ON ...)
4️⃣ 确定筛选与聚合(WHERE / GROUP BY / HAVING / ORDER BY)
案例:查询每个学院学生平均成绩TOP3
FROM students s
INNER JOIN scores sc ON s.id = sc.student_id
GROUP BY s.college, s.major
ORDER BY avg_score DESC
LIMIT 3;
教材结合B+树原理,总结索引设计原则:
- ✅ 前缀索引:对长字符串字段(如URL)取前N字符建索引
- ✅ 覆盖索引:查询字段全在索引中(如
SELECT name FROM users WHERE id=10) - ❌ 避免在索引列上使用函数(如
WHERE YEAR(birth)=1998) - ✅ 复合索引遵循最左前缀原则(
(a,b,c)可命中a或a,b,但无法命中b)
教材深入剖析四大特性如何落地:
- A(原子性):通过Undo Log实现——操作失败时回滚到事务前状态
- C(一致性):由应用层+约束(外键/唯一/检查)共同保障
- I(隔离性):通过锁+MVCC实现,教材详细对比READ UNCOMMITTED→SERIALIZABLE的差异
- D(持久性):Redo Log缓冲池刷盘机制保障
? 教材强调:隔离级别不是越高越好!SERIALIZABLE虽绝对安全,但并发性能下降90%;一般OLTP系统用READ COMMITTED即可兼顾性能与一致性。
教材采用“时间线+数据表”双视角展示并发问题:
| 隔离级别 | 脏读 | 不可重复读 | 幻读 |
|---|---|---|---|
| READ UNCOMMITTED | ✅ | ✅ | ✅ |
| READ COMMITTED | ❌ | ✅ | ✅ |
| REPEATABLE READ | ❌ | ❌ | ✅(MySQL通过MVCC+Gap Lock解决) |
| SERIALIZABLE | ❌ | ❌ | ❌ |
? MySQL默认为REPEATABLE READ,PostgreSQL为READ COMMITTED——选择时需结合业务容忍度。
教材在“扩展篇”引入现代分布式场景:
- 2PC(两阶段提交):强一致性,但阻塞时间长,适用于金融核心系统
- TCC(Try-Confirm-Cancel):业务层实现,高可用但开发复杂(如订单预占库存→确认→取消)
- Saga模式:补偿机制,最终一致性,适用于电商订单(创建订单→扣库存→支付→发送通知)