跳转到主要内容

目录

DDIA 第二版完整目录:十四章,涵盖数据系统基础、分布式数据与派生数据。

这份目录与左侧章节树、页末顺序导航共享同一阅读顺序;章内标题直接来自各页的稳定锚点。选择任意条目即可进入对应章节或小节。

插图目录

全书编号插图使用稳定图号和锚点;正文中的“图 N-N”引用会同时链接到这里列出的目标。

  1. 图 1-1 — 将数据通过 ETL 导入数据仓库的简化示意图。
  2. 图 1-2 — 软件类型及其运维方式的连续谱。
  3. 图 2-1 — 一个允许用户相互关注的社交网络的简单关系模式。
  4. 图 2-2 — 扇出——把新帖子投递给发帖用户的每一位关注者。
  5. 图 2-3 — 当服务的吞吐量接近其处理能力上限时,排队会使响应时间急剧增加。
  6. 图 2-4 — 响应时间、服务时间、网络延迟和排队延迟。
  7. 图 2-5 — 用 100 次服务请求的响应时间样本说明平均值和分位数。
  8. 图 2-6 — 当一次请求需要多个后端调用时,只需一个慢调用,就会拖慢整个最终用户请求。
  9. 图 3-1 — 使用关系模式表示 LinkedIn 个人资料。
  10. 图 3-2 — 一对多关系形成树状结构。
  11. 图 3-3 — 关系模型中的多对多关系。
  12. 图 3-4 — 文档模型中的多对多关系;每个虚线框内的数据可以组成一份文档。
  13. 图 3-5 — 用于数据仓库的星型模式示例。
  14. 图 3-6 — 图结构数据示例(框表示顶点,箭头表示边)。
  15. 图 3-7 — 使用示例 3-12 中的 Datalog 规则确定爱达荷州在北美。
  16. 图 3-8 — 以不可变事件日志作为权威数据源,并从中派生物化视图。
  17. 图 3-9 — 将电影评分的关系数据库转换为矩阵表示。
  18. 图 4-1 — 以类似 CSV 的格式存储键值对日志,并使用内存哈希映射建立索引。
  19. 图 4-2 — 带有稀疏索引的 SSTable,查询可以直接跳到正确的数据块。
  20. 图 4-3 — 合并多个 SSTable 段,仅保留每个键的最新值。
  21. 图 4-4 — 布隆过滤器以概率方式快速判断某个键是否存在于某个 SSTable 中。
  22. 图 4-5 — 使用 B 树索引查找键 251。先从根页沿引用进入键 200–300 所在的页,再进入键 250–270 所在的页。
  23. 图 4-6 — 在边界键 337 处拆分页,使 B 树增长;父页也随之更新,以引用两个子页。
  24. 图 4-7 — 按列而不是按行存储关系数据。
  25. 图 4-8 — 对单列进行压缩并建立位图索引的存储方式。
  26. 图 4-9 — 两张位图的按位与运算非常适合向量化处理。
  27. 图 4-10 — 多维数据集的两个维度,通过求和聚合数据。
  28. 图 4-11 — 在 HNSW 索引中查找最接近给定查询向量的数据库条目。
  29. 图 5-1 — 旧版应用程序更新先前由新版应用程序写入的数据时,若处理不慎,可能丢失数据。
  30. 图 5-2 — 示例 5-2 中的记录使用 MessagePack 编码后的结果。
  31. 图 5-3 — 使用 Protocol Buffers 编码的示例记录。
  32. 图 5-4 — 使用 Avro 编码的示例记录。
  33. 图 5-5 — Protocol Buffers 的编码与解码可以使用不同版本的模式。Avro 解码时使用两个模式:写入者模式必须与编码时所用模式完全相同,读取者模式则可以是较旧或较新的版本。
  34. 图 5-6 — Avro 读取器协调写入者模式与读取者模式之间的差异。
  35. 图 5-7 — 使用图形化的业务流程模型与标记法(BPMN)表示工作流的示例。
  36. 图 II-1 — 一个数据库切分为两个分区,每个分区都有两个副本
  37. 图 6-1 — 单主复制把所有写入都发往指定的领导者,再由领导者将变更流发送给各追随者副本。
  38. 图 6-2 — 基于领导者的复制,其中一个追随者同步复制,另一个异步复制。
  39. 图 6-3 — 用户写入后,又从陈旧副本读取。要防止这种异常,需要写后读一致性。
  40. 图 6-4 — 用户先从较新的副本读取,随后从陈旧副本读取,时间仿佛倒退了。要防止这种异常,需要单调读。
  41. 图 6-5 — 如果某些分片的复制速度慢于其他分片,观察者可能先看到答案,后看到问题。
  42. 图 6-6 — 跨多个地区的多主复制。
  43. 图 6-7 — 多主复制可以采用的三种拓扑示例。
  44. 图 6-8 — 在多主复制中,写入抵达某些副本的顺序可能有误。
  45. 图 6-9 — 两个领导者并发更新同一条记录,造成写入冲突。
  46. 图 6-10 — 亚马逊购物车异常示例:以并集方式合并购物车冲突时,已删除的商品可能重新出现。
  47. 图 6-11 — OT 与 CRDT 分别如何合并字符串中的两次并发插入。
  48. 图 6-12 — 节点停机后的仲裁写、仲裁读和读修复。
  49. 图 6-13 — 如果 w + r > n,读取的 r 个副本中至少有一个必然见过最近一次成功写入。
  50. 图 6-14 — Dynamo 风格数据存储中的并发写入没有明确定义的顺序。
  51. 图 6-15 — 捕获两个客户端并发编辑购物车时的因果依赖。
  52. 图 6-16 — 图 6-15 中因果依赖关系的图示。
  53. 图 7-1 — 复制与分片结合使用:每个节点对某些分片充当领导者,对另一些分片充当追随者。
  54. 图 7-2 — 印刷版百科全书按键范围分片。
  55. 图 7-3 — 通过对键进行哈希并取模节点数来将键分配给节点。更改节点数会导致许多键从一个节点移动到另一个节点。
  56. 图 7-4 — 向每个节点有多个分片的数据库集群添加新节点。
  57. 图 7-5 — 为每个分片分配连续的哈希值范围。
  58. 图 7-6 — Cassandra 和 ScyllaDB 将可能的哈希值范围(这里是 0–1023)拆成边界随机的连续区间,并为每个节点分配多个区间。
  59. 图 7-7 — 将请求路由到正确节点的三种不同方式。
  60. 图 7-8 — 使用 ZooKeeper 跟踪分片到节点的分配。
  61. 图 7-9 — 本地二级索引:每个分片只索引其自己分片内的记录。
  62. 图 7-10 — 全局二级索引反映来自所有分片的数据,并且本身按索引值进行分片。
  63. 图 8-1 — 两个客户端并发递增计数器之间的竞态条件。
  64. 图 8-2 — 违反隔离性:一个事务读取另一个事务的未提交写入(“脏读”)。
  65. 图 8-3 — 原子性确保如果发生错误,该事务的任何先前写入都会被撤消,以避免不一致的状态。
  66. 图 8-4 — 没有脏读:用户 2 只有在用户 1 的事务提交后才能看到 x 的新值。
  67. 图 8-5 — 发生脏写时,不同事务的冲突写入可能混杂在一起。
  68. 图 8-6 — 读偏差:Aaliyah 观察到了数据库的不一致状态。
  69. 图 8-7 — 使用多版本并发控制实现快照隔离。
  70. 图 8-8 — 写偏差导致应用程序错误的示例。
  71. 图 8-9 — 交互式事务与存储过程的差异(采用图 8-8中的示例事务)。
  72. 图 8-10 — 检测事务何时从 MVCC 快照读取过时值。
  73. 图 8-11 — 在可串行化快照隔离中,检测一个事务何时修改了另一个事务读过的数据。
  74. 图 8-12 — 当事务涉及多个数据库节点时,它可能在某些节点上提交,在其他节点上失败。
  75. 图 8-13 — 两阶段提交(2PC)的成功执行。
  76. 图 8-14 — 参与者投票“是”之后,协调者崩溃。数据库 1 不知道该提交还是中止。
  77. 图 9-1 — 发出请求却没有收到响应时,无法分辨究竟是 (a) 请求丢失、(b) 远程节点宕机,还是 (c) 响应丢失。
  78. 图 9-2 — 多台机器向同一个目的地发送网络流量时,交换机队列可能被塞满。图中端口 1、2 和 4 都在尝试向端口 3 发送数据包。
  79. 图 9-3 — 客户端 B 的写入在因果关系上晚于客户端 A 的写入,但 B 的写入具有更早的时间戳。
  80. 图 9-4 — 分布式锁的错误实现:租约已经过期,客户端 1 却认为它依然有效,因而损坏了存储中的文件。
  81. 图 9-5 — 原租约持有者发出的消息可能延迟很久,直到另一个节点接管租约后才抵达。
  82. 图 9-6 — 只允许写入按照递增的栅栏令牌顺序执行,从而保证存储访问安全。
  83. 图 9-7 — 使用栅栏令牌保护对无主复制数据库的写入。
  84. 图 10-1 — 如果这个数据库满足线性一致性,那么 Alice 的读取应返回 1 而不是 0,或者 Bob 的读取应返回 0 而不是 1。
  85. 图 10-2 — 如果读请求与写请求并发,则可能返回旧值,也可能返回新值。
  86. 图 10-3 — 如果 Alice 和 Bob 拥有完美时钟,线性一致性要求读取返回 x = 1,因为对 x 的读取开始于 x = 1 写入完成之后。
  87. 图 10-4 — 对 x 的读取与 x = 1 的写入并发。由于不知道操作的确切时序,读取可以返回 0 或 1。
  88. 图 10-5 — 一个不满足线性一致性的系统:Alice 和 Bob 在不同时刻看到上传的图像,因此 Bob 的请求建立在陈旧数据之上。
  89. 图 10-6 — 当网络延迟变化不定时,仅靠法定人数不足以保证线性一致性。
  90. 图 10-7 — 如果网络分区使客户端无法联系足够多的副本,它们就无法处理写入。
  91. 图 10-8 — 两个不同节点可能生成相互冲突的 ID。
  92. 图 10-9 — Lamport 时间戳给出了与因果关系一致的全序。
  93. 图 10-10 — 一个使用 Lamport 时间戳的权限系统。
  94. 图 11-1 — 一个包含三个 mapper 和三个 reducer 的 MapReduce 作业。
  95. 图 11-2 — 用户活动日志与用户画像数据库的连接。
  96. 图 11-3 — 基于用户 ID 的排序合并连接。若输入数据集由多个文件分片组成,可并行启动多个 mapper 处理。
  97. 图 12-1 — (a)负载均衡:由多个消费者分担一个主题的消费工作;(b)扇出:将每条消息传递给多个消费者。
  98. 图 12-2 — 消费者 2 在处理 m3 时崩溃,因此 m3 稍后被重新传递给消费者 1。
  99. 图 12-3 — 生产者把消息追加到主题分区文件中,消费者则顺序读取这些文件。
  100. 图 12-4 — 数据库中的 X 先被设为 A,再被设为 B;写入到达搜索索引的顺序却恰好相反。
  101. 图 12-5 — 按数据写入一个数据库的顺序取得数据,再按相同顺序将变化应用到其他系统。
  102. 图 12-6 — 一个键值对日志:键是猫咪视频的 ID(mew、purr、scratch 或 yawn),值是播放次数。日志压实只保留每个键的最新值。
  103. 图 12-7 — 应用当前状态与事件流之间的关系。
  104. 图 12-8 — 按处理时间划分窗口,会因处理速率的变化而产生人为假象。
  105. 图 13-1 — 在搜索索引中,写入(文档更新)与读取(查询)相遇。
  106. 图 13-2 — 使用事件日志和流处理器,检查源账户是否有足够余额,并把资金原子地转入目标账户和手续费账户。

表格目录

  1. 表 1-1 — 事务型系统与分析型系统的特征比较
  2. 表 1-2 — 自托管数据库系统与云原生数据库系统示例
  3. 表 8-1 — 各种隔离级别下可能发生的异常汇总。

示例目录

  1. 示例 3-1 — 将 LinkedIn 个人资料表示为 JSON 文档
  2. 示例 3-2 — 通过 ID 引用组织的简历
  3. 示例 3-3 — 使用关系模式表示属性图
  4. 示例 3-4 — 图 3-6 中的一部分数据,以 Cypher 查询表示
  5. 示例 3-5 — 查找从美国移居欧洲者的 Cypher 查询
  6. 示例 3-6 — 使用递归公用表表达式,以 SQL 写出与示例 3-5 相同的查询
  7. 示例 3-7 — 图 3-6 中的一部分数据,以 Turtle 三元组表示
  8. 示例 3-8 — 示例 3-7 中数据的简洁写法
  9. 示例 3-9 — 使用 RDF/XML 语法表示示例 3-8 中的数据
  10. 示例 3-10 — 与示例 3-5 相同的查询,用 SPARQL 表示
  11. 示例 3-11 — 图 3-6 中数据的子集,表示为 Datalog 事实
  12. 示例 3-12 — 与示例 3-5 相同的查询,用 Datalog 表示
  13. 示例 3-13 — 群聊应用的 GraphQL 查询示例
  14. 示例 3-14 — 对示例 3-13 中查询的一种可能响应
  15. 示例 4-1 — 分析人们在一周中的哪一天更倾向于购买新鲜水果或糖果
  16. 示例 5-1 — 以整数为键、字符串为值的 JSON 模式示例。由于 JSON 模式要求所有键均为字符串,整数键表示为只包含数字的字符串。
  17. 示例 5-2 — 本章将使用多种二进制格式编码的示例记录
  18. 示例 5-3 — 使用 YAML 编写的 OpenAPI 服务定义示例
  19. 示例 5-4 — 使用 FastAPI 实现示例 5-3 中定义的服务
  20. 示例 5-5 — 用于图 5-7 所示支付工作流的 Temporal 工作流定义片段
  21. 示例 8-1 — 显式锁定行以防止丢失更新
  22. 示例 8-2 — 会议室预订系统试图避免重复预订(在快照隔离下并不安全)