书 · 1986 · 亚伯拉罕·西尔伯沙茨、亨利·F.科思、S.苏达尔尚(苏达尔尚自第三版加入)

《数据库系统概念》

计算机与 AI书单第 30 名

一句话结论

数据库的本事,是让不断变化的数据在多人使用、机器故障和规模增长时,仍然能够被清楚表达、高效查询和可靠更新。

值不值得读完整本?

值得完整读完基础主线,进阶章节可以按需要选读。它把数据模型、查询执行和可靠性连成一套解释,能帮助你从“会写查询”走到“理解数据库为什么这样工作”。

  • 版本先说明:1986年初版只有西尔伯沙茨和科思两位作者,苏达尔尚于1997年第三版加入。本导读的章号、例子和新增主题依据2019年英文第七版,不是1986年初版目录。
  • 先读第1—4章,掌握数据抽象、关系模型、基本查询、连接、聚合、视图和约束;再读第6—7章,练习把现实规则变成数据库设计。
  • 接着细读第12—16章和第17—19章。前一组解释查询为什么快或慢,后一组解释并发与故障为什么不会轻易把数据弄坏。
  • 再读第20—23章,理解单机原理迁移到多机后增加了哪些协调成本;第10—11章可配合阅读,用来比较大数据分析与日常事务处理的需求。
  • 第5章、第8—9章及第24—32章可以按项目需要分批补读,其中在线补充章节不必第一遍全部精读;应用安全部分建议至少浏览。
  • 必须配合练习:亲手写查询、判断分解是否无损、比较执行计划、推演并发读写和崩溃恢复。下面的选择题覆盖六条核心主线,但不能替代这些操作。

核心观点

1. 把数据的含义与存放方式分开

应用应主要依赖数据的逻辑结构,而不是记录在磁盘上的具体位置。关系模型用表、键和关系表达数据,数据库负责把这些表达映射到物理存储。

为什么:如果程序直接依赖文件布局,换一种索引或存储方式就可能迫使许多程序跟着修改。数据库把物理层、逻辑层和用户看到的视图分开,让变化尽量留在相应层次内。声明式查询进一步让使用者描述需要什么数据,把具体访问路径交给系统选择。这种分工降低了维护成本,也为系统独立改进性能留下空间。

2. 数据库设计要减少重复事实,并保住约束

先用实体、联系和约束描述业务,再用函数依赖检查表的组织方式。规范化的目标是减少有害冗余,同时保证分解无损,并尽可能保持依赖。

为什么:同一个事实若在许多行中重复,修改时就可能漏掉某些副本,造成相互矛盾的数据。函数依赖把“哪些属性决定哪些属性”的业务规则明确写出来,帮助定位这种冗余。分解必须能够通过连接准确重建原有信息,否则可能产生原本不存在的组合。保持依赖则让许多约束可以在单表内检查,避免每次更新都做昂贵的跨表检查;这些目标有时需要取舍。

3. 查询结果由语义决定,查询速度由执行方案决定

同一个查询可以有多种正确的执行方式。存储布局、缓冲、索引、连接算法和操作顺序,共同决定执行成本。

为什么:逻辑上等价的操作顺序,可能产生大小相差悬殊的中间结果,进而改变读写量和计算量。索引能减少某些查询的访问范围,但也占用空间,并增加更新时的维护工作。优化器根据数据量、值分布和可用访问路径估算不同计划的成本,再选择较合适的方案。估算依赖统计信息与模型,因此选中的计划不保证在实际运行中总是最快。

4. 并发要有正确性标准,事务不能只是一组语句

事务把一个逻辑工作单元组织起来,要求原子性、一致性、隔离性和持久性。并发控制的重要标准是可串行化:允许操作交错,但执行语义应等价于某种串行次序。

为什么:两个单独执行都正确的事务,交错后仍可能读到不合适的中间状态,或覆盖彼此的更新。可串行化把难以逐一分析的交错执行,转化为与串行执行比较的问题。锁、时间戳和多版本协议通过限制冲突或安排可见版本来控制这种交错。更强的隔离往往增加等待、检查或回滚成本,所以书中也介绍较弱隔离及其允许的异常。前提仍是事务本身遵守业务规则,数据库不会自动理解全部业务意图。

5. 恢复依靠可重建的历史,而不是指望机器不坏

原子性和持久性需要恢复机制支撑。日志、先写日志规则和检查点,使系统能在崩溃后撤销不应保留的修改,并重建应当保留的结果。

为什么:数据页在内存与持久存储之间分批移动,崩溃时磁盘内容未必恰好对应某个完整事务边界。先写日志要求相关恢复信息先于数据页持久化,避免数据已改变却没有办法追溯。确认提交前保存必要日志,则允许提交时不立即写出全部修改过的数据页。恢复算法据此完成必要的撤销与重做,检查点帮助缩小恢复工作范围;若存储介质本身损坏,还需要备份等措施。

6. 分布式扩大能力,也扩大协调问题

分区把数据和计算分散到多台机器,复制增加冗余与服务能力。它们带来扩展和容错机会,同时引入通信、负载倾斜、副本一致性与跨节点提交问题。

为什么:独立部分可以并行处理,但跨分区连接和事务需要传输数据或协调决定。任务分配不均时,最繁忙的节点可能限制整体速度,因此增加机器未必带来同比例收益。复制让单个节点故障后仍可能继续服务,却要求系统处理副本间的更新顺序与可见性。跨节点事务必须协调提交或中止,基础两阶段提交在某些故障下会等待协调者恢复。系统设计因此需要结合负载与故障条件,选择分区、复制和一致性方案。

反对意见

关系理论与SQL应当分开评价(Hugh Darwen、C. J. Date)

Darwen与Date在《The Third Manifesto》中批评SQL对关系模型的偏离,包括重复元组与空值等设计,并提出结合关系理论和类型系统的语言方向。其核心理由是:语言若引入额外语义,就会增加推理和约束表达的复杂性。这提醒读者,教材讲授SQL的实用规则,并不意味着SQL就是关系理论的完整体现;这不是针对本书的直接书评。

通用原理不等于一种引擎适合所有负载(Michael Stonebraker、Uğur Çetintemel)

两人在《“One Size Fits All”: An Idea Whose Time Has Come and Gone》中主张,围绕传统事务处理形成的通用数据库架构,难以同时高效满足数据仓库和流处理等需求。不同负载的访问方式与处理目标不同,专用引擎可以据此调整内部组织。这为教材的通用知识框架补充了工程边界,并不否定其中的关系理论或事务原理。

应用可以组合多种存储模型(Pramod J. Sadalage、Martin Fowler)

两人在《NoSQL Distilled》中主张根据应用需要组合使用不同存储技术,而不是预先把所有问题交给关系数据库。大规模集群、不同数据模型及一致性取舍,为这种选择提供了理由。他们仍认可关系数据库的长期价值,因此分歧在于工具的选择范围,而不是关系数据库是否应该被淘汰;这也是对照阅读,不是直接批评本书。

相关推荐

导读由 AI 根据公开资料整理,没有读取原书全文,一切以原著为准。导读 Primer 首页