# 关系数据库：选教材，先核对查询在数什么 — 学习任务单

[学习指南](https://unireadinglist.com/zh-cn/guides/relational-databases/)

[课程专题: 数据库系统](https://unireadinglist.com/zh-cn/subjects/computer-science/#course-databases)

来源核验日期: 2026-11-04

学习路线与例题编辑责任：University Reading List 编辑项目。

这是本科关系设计与查询语义路线，不是生产数据库管理指南。可执行例子采用SQLite3，并以SQLite3.51.0内存数据库核对。房间和预约行全属虚构；作者在线草稿仅作后续理论读物，不是当前产品操作手册。

## 选择你的起点

- [ ] 需要免费设计入门
  用Watt/Eng学实体、关系、键和规范化，再用小数据核对SQL；始终说明所用方言。

- [ ] 需要贯穿课程的系统参考
  用Database System Concepts第七版，将关系语言和设计放在存储、事务与处理之前。

- [ ] 会查询，但要理解形式依据
  学过离散数学与逻辑后再读Foundations，研究查询、约束与表达能力，不期待它提供最新引擎教程。

## 三本书如何取舍

### Database Design

Adrienne Watt; Nelson Eng · 2 · 2014
免费设计主线

适合何时选择: 需要从实体、依赖关系到表的清晰导入。
何时另选路线: 希望一书包揽高级并发、代价优化与所有当前方言。
建议阅读范围: 第二版第7–12章，再读15–16章；实体关系不清楚则回到早期建模章。
局限与取舍: BCcampus确认2014版及SQL增补；教材例子不自动代表每个当前引擎的行为。

#### 选书前试做

区分房间、预约、标签，标明键及每个关系可能产生的行数。
检查标准: 一个预约可有多标签，连接会改变行粒度；实体名称不能证明一对一。

你的笔记:

________________________________

[官方免费阅读](https://opentextbc.ca/dbdesign01/)

[书目信息与获取方式](https://unireadinglist.com/zh-cn/subjects/computer-science/database-design-watt-eng/)

### Database System Concepts（数据库系统概念）

Abraham Silberschatz; Henry F. Korth; S. Sudarshan · 7 · 2019
关系语言与系统参考

适合何时选择: 课程除设计外还讲查询和事务等系统概念。
何时另选路线: 只需短设计导论，或误以为公开配套就是完整商业正文。
建议阅读范围: 第七版第2–4、6–7章；关系基础之后再选第17章事务。
局限与取舍: 作者确认2019年3月和ISBN9780078022159。公开目录、幻灯片、练习资料与全书权限有别。

#### 选书前试做

读3.6–3.7及4.1后，先预测例子中三种COUNT与SUM，再运行。
检查标准: 无预约的房间与人数未知的预约不同，即使两者SUM都显示NULL。

你的笔记:

________________________________

ISBN: 9780078022159

[书目信息与获取方式](https://unireadinglist.com/zh-cn/subjects/computer-science/database-system-concepts/)

### Foundations of Databases

Serge Abiteboul; Richard Hull; Victor Vianu · Complete authors’ online draft
形式查询伴读

适合何时选择: 已懂关系设计，想论证查询、约束和表达能力。
何时另选路线: 需要第一门SQL、产品配置，或把保留重复的SQL直接当作集合论。
建议阅读范围: 在合法草稿中定位关系模型、查询语言与依赖关系；不指定未核实的当前页码或章号。
局限与取舍: 书目保留作者在线草稿身份，不冒充新核验的纸本版；本次端点无法读取，主线用可访问的Watt，并先确认自己的合法访问。

#### 选书前试做

把小查询表示成数学关系，再说明SQL保留相同行时需改变哪些假设。
检查标准: 区分集合成员与重复次数、NULL与普通值；同值主张必须写清语义前提。

你的笔记:

________________________________

[官方免费阅读](https://webdam.di.ens.fr/Alice/)

[书目信息与获取方式](https://unireadinglist.com/zh-cn/subjects/computer-science/foundations-databases-abiteboul-hull-vianu/)

## 检查先修准备

### 键能说明什么？

你的笔记:

________________________________

### LEFT JOIN后的COUNT(\*)为何易误导？

你的笔记:

________________________________

### NULL就是零吗？

你的笔记:

________________________________

## 六步学习与具体成果

- [ ] 选择行粒度

建议阅读范围: Watt第7–10章，系统书第2章。

动手产出: 画房间、预约与标签关系，说明一行代表什么。

检查标准: 房间ID与预约ID不是同一计数单位。

你的笔记:

________________________________

- [ ] 声明依赖

建议阅读范围: Watt第11–12章及关系设计章节。

动手产出: 写候选键、函数依赖及合理分解。

检查标准: 依据是领域规则，不是仅三行样本的偶然。

你的笔记:

________________________________

- [ ] 预测连接

建议阅读范围: Watt第15–16章，系统书4.1。

动手产出: 聚合前手写LEFT JOIN的每一行。

检查标准: 保留C的补空行，以及人数相同但各自独立的两个A预约。

你的笔记:

________________________________

- [ ] 选择分母

建议阅读范围: 系统书3.6–3.7与SQLite聚合参考。

动手产出: 逐房间解释三种计数和一个合计。

检查标准: 表达式回答不同问题；执行成功不是解释。

你的笔记:

________________________________

- [ ] 测试倍增

建议阅读范围: 后续变式与形式伴读的查询观点。

动手产出: 加入标签，追踪粒度并修复连接，不抹去合法重复值。

检查标准: 逐连接核对基数，DISTINCT不是万能修复。

你的笔记:

________________________________

- [ ] 写可复现说明

建议阅读范围: 返回能解决薄弱点的教材。

动手产出: 记录模式前提、方言、输入、查询、期望输出和反例。

检查标准: 能复现NULL和重复行为，不等于证明并发或性能。

你的笔记:

________________________________

## 原创例题与解析: 原创SQL例题：没匹配到记录，不等于值未知

虚构房间表为A、B、C；预约(id,room,seats)为(1,A,2)、(2,A,2)、(3,B,NULL)，C无预约。LEFT JOIN后逐房间预测COUNT(\*)、COUNT(booking.id)、COUNT(booking.seats)、SUM(booking.seats)。

前提假设: 预约ID唯一且非NULL；人数NULL表示未知，不是取消或零。登记表在本例完整，查询期间无改动。SQL保留两个相等已知值，采用SQLite3聚合及左连接语义。

你的笔记:

________________________________

## 改变假设，再做一题: 变式：描述行让度量被重复累计

保留预约，新增标签(1,red)、(1,blue)、(2,red)。聚合前LEFT JOIN标签，A会怎样？如何保留标签数又不改变预约度量？

你的笔记:

________________________________

## 进入下一阶段之前

- 能解释每列与行粒度。
- 能区分无匹配、未知与已测零。
- 能构造错误连接或DISTINCT修复的反例。

## 答案与解释

### 键能说明什么？

它在声明的约束下标识行。三个样本值碰巧不同，不能证明所有允许状态都满足键约束。

### LEFT JOIN后的COUNT(\*)为何易误导？

它也数左侧无匹配时补出的NULL行。要数匹配记录，应数右侧非空标识符。

### NULL就是零吗？

不是。未知值、已测零和根本没有预约是三种情况，替换前先写报告规则。

### 原创SQL例题：没匹配到记录，不等于值未知

1. A匹配两个独立预约，四个输出为2、2、2、4。SUM(DISTINCT seats)却为2，会错误抹掉合法的重复值。
2. B匹配预约3：1、1、0、NULL。有预约但没有已知人数，SUM在无非NULL输入时返回NULL。
3. C得到一条补空行：1、0、0、NULL。COUNT(\*)虽为1，匹配预约却为零，不能混同两种计数。
4. 若报告约定无预约显示零，应明确该规则。把所有NULL合计替为零，也会把B的未知人数写成虚假的测量。

按所问列序，A:(2,2,2,4)，B:(1,1,0,NULL)，C:(1,0,0,NULL)。先解释各列再称其为预约数或总人数。

## 原创SQL例题：没匹配到记录，不等于值未知 — sql

```sql
WITH room(room_id) AS (VALUES ('A'), ('B'), ('C')),
booking(id, room_id, seats) AS (
  VALUES (1, 'A', 2), (2, 'A', 2), (3, 'B', NULL)
)
SELECT r.room_id, COUNT(*) AS joined_rows,
       COUNT(b.id) AS bookings, COUNT(b.seats) AS known_counts,
       SUM(b.seats) AS seats
FROM room AS r
LEFT JOIN booking AS b ON b.room_id = r.room_id
GROUP BY r.room_id
ORDER BY r.room_id;
```

检验结果: 在空SQLite会话执行单条语句；把B的NULL改为0后，已知值数变1、合计0，预约数仍1，说明未知与零不能混合。

### 改变假设，再做一题: 变式：描述行让度量被重复累计

1. 预约1出现两次、预约2一次，A有三条连接行，简单人数和2+2+2=6；实际只有两个预约，已知人数和4。
2. 先把标签缩成每预约一行，计数为2和1，再与唯一预约连接。A仍是预约2、人数4，标签数3。
3. SUM(DISTINCT seats)得2仍错。即使先聚合预约，后续多侧连接再次复制聚合值，也没有修好；最终关系必须保持度量粒度。

累计预约度量时保持每预约一行，或先分别算预约与标签的房间级摘要，再一对一连接。修复依据是键和基数，而不是加一个DISTINCT。

检验结果: 列中间行，核对A的2/4/3。标签不会为B补出一项人数测量，未知仍然未知。

## 常见误区

### 行等于实体

连接行不自动等于一个顾客、预约或房间，先定义粒度。

### 没有规则就替换NULL

COALESCE可实现明确的展示约定，却不能发现缺失测量。

### 把样本当约束证明

样本唯一或测试通过不能证明键、依赖及所有允许状态的正确性。

## 来源与版次核验

- [BCcampus: Database Design second-edition contents and access](https://opentextbc.ca/dbdesign01/)
  确认2014第二版、章序和官方免费入口；任务为本站原创。

- [Authors: Database System Concepts, seventh-edition identity](https://www.db-book.com/)
  作者确认第七版、2019与所选ISBN；不把公开配套称作全书。

- [Authors: seventh-edition contents](https://www.db-book.com/toc-dir/toc.pdf)
  作者目录核实查询、设计及事务章目。

- [Authors: Foundations of Databases online draft](https://webdam.di.ens.fr/Alice/)
  保留作者草稿身份；本次访问失败不构成猜测新年份、纸本ISBN或再用许可的依据。

- [SQLite: built-in aggregate semantics](https://www.sqlite.org/lang_aggfunc.html)
  COUNT及SUM/NULL按引擎官方参考核对。

- [SQLite: SELECT and join processing](https://www.sqlite.org/lang_select.html)
  LEFT JOIN补空与处理顺序按官方SELECT资料核对，不是生产管理说明。

这些是本站建议的学习活动，并非大学官方作业，也不代表对每本书逐页通读。

[编辑与选书方法](https://unireadinglist.com/zh-cn/editorial/)
