ADB-02 分布式数据库
ADB-02 分布式数据库
📅 预计 70 分钟 | ⭐ = 重要知识点 | 📌 中英术语见文末
📖 架构与协议概念为主,配文字分步推演
2.1 分布式数据库系统概念
一家开分店的连锁书店
想象一家连锁书店:最初只有总店一间,所有书都堆在里面,读者都要跑去总店借——这是集中式。后来它在不同城市开了分店,每家分店存一部分书,但借书卡全国通用,你在任何一家分店都能查到全公司的藏书目录,仿佛只有一座图书馆——书(数据)分散存放,但目录(逻辑)是统一的,这就是分布式数据库的雏形。
定义:物理分散,逻辑统一
分布式数据库系统(Distributed Database System,DDBS)= 分布式数据库(DDB)+ 分布式数据库管理系统(DDBMS)。核心定义八个字:
数据分散存储在多节点、逻辑上统一。
- 物理分散:数据存放在通过计算机网络连接的多个节点(site)上,不是堆在一台机器里。
- 逻辑统一:对用户而言,整个系统仍表现为一个数据库,用户可以像操作单机数据库一样提交查询,无需知道数据存在哪个节点。这种"隐藏位置信息"的能力叫位置透明性(location transparency)。
与集中式的对比
| 维度 | 集中式数据库 | 分布式数据库 |
|---|---|---|
| 数据存放 | 单节点 | 多节点分散 |
| 逻辑视图 | 单一 | 单一(对用户透明) |
| 控制 | 集中控制 | 分散,节点局部自治 |
| 可用性 | 单点故障即整体不可用 | 部分节点故障,其余仍可用 |
| 扩展 | 垂直扩展(换更强主机) | 水平扩展(加节点即可) |
| 一致性 | 本地锁与日志即可 | 需跨节点协调(如 2PC) |
优点与挑战
优点(为什么值得做):
- 高可用 ⭐:一台机器挂了不等于系统挂了,故障节点可下线修复,其余节点照常服务。
- 可扩展 ⭐:数据涨了,加一台机器、挪一部分数据过去就行,不必换更贵的大型机。
- 局部自治:每个节点独立管理自己的数据,业务按地域或部门划分时很自然。
挑战(为什么难):
- 一致性 ⭐:多个节点各持一份数据,更新时要保证大家看到的一致,需要协调协议,这是分布式最棘手的部分。
- 网络开销:每次跨节点查询、多节点事务都要在网络上传输数据,网络延迟可能抵消"就近访问"的好处。
- 复杂度:分片、副本、故障恢复、分布式事务,设计、部署、排错的难度都比集中式高一个量级。
⚠️ 常见错误
- 只记"物理分散",漏掉"逻辑统一":没有逻辑统一,用户须自己连对应库,那只是"多台独立数据库连了网",不是分布式数据库。
- 以为分布式一定更快:跨节点查询和网络传输有开销,单机瞬间能完成的查询被分散后可能更慢——分布式的收益是可用性与扩展性。
- 把"高可用"当成"不出错":高可用指"故障时系统仍能服务",代价是一致性或复杂度。
2.2 体系结构:三层模式映射
一本被拆开的书
把整个数据库想成一本书《学生档案》。全局模式是书的"目录",讲整本书讲什么;分片模式是"怎么切章"——拆成"第一章 个人信息、第二章 成绩";分配模式是"每章放哪个书架"。读者只看到目录,不关心书被拆成几本、放在哪个馆。
三层模式:从"长什么样"到"放哪里"
- 全局模式(Global Schema) ⭐:相当于集中式数据库的概念模式,用全局的逻辑结构描述整个分布式数据库。用户看到的就是它。
- 分片模式(Fragmentation Schema) ⭐:回答"怎么切"。全局关系被划分为若干逻辑片断(fragment),每个片断仍是一个关系。分片只做逻辑划分,还没决定物理位置。
- 分配模式(Allocation Schema) ⭐:回答"放哪里"。把每个片断映射到一个或多个节点(单副本还是多副本),逻辑片断就此落到物理站点。
映射链:全局模式 → 分片模式 → 分配模式 → 物理存储。
客户端/服务器模式 与 对等(P2P)模式
- 客户端/服务器模式(Client/Server):角色不对称。服务器负责存储数据和执行查询,客户端只发请求、展示结果。
- 对等模式(Peer-to-Peer,P2P):各节点地位平等,既是"客户端"(能发请求)又是"服务器"(能存数据、提供服务),没有中心节点,容错性和扩展性更强。
⚠️ 常见错误
- 分不清"分片模式"和"分配模式":分片是"切"、分配是"放",先切后放。
- 以为全局模式是真实存储的表:全局模式只是逻辑描述,真实数据切分后分布在各节点。
- 把"客户端/服务器"当成"非分布式":C/S 也是分布式的一种形态,与对等模式的区别在于角色是否对称。
2.3 数据分片:怎么把一张大表切开
切西瓜的三种切法
一个大西瓜(一张关系表)怎么分给几桌客人?顺着纹理竖切成瓣,每瓣属性齐全——对应水平分片;只切瓜瓤,每份只含部分属性——对应垂直分片;先竖切再挖瓤——对应混合分片。
四种分片方式
- 水平分片(Horizontal Fragmentation) ⭐:按行切,每个片断是原关系满足某条件的一个元组子集。例:
学生(学号,姓名,学院)按学院切——计算机学院的学生、软件学院的学生……各片属性列完全相同,只是行数不同。 - 垂直分片(Vertical Fragmentation) ⭐:按列切,把属性分成几组。例:
学生切成(学号,姓名,学院)和(学号,成绩)。注意主键(学号)必须留在每个片断里,否则没有公共列,拼不回来。 - 导出分片(Derived Fragmentation):跟随别的表切。例:
选课表跟着学生表的水平分片走,凡"计算机学院学生"的选课记录放一片。这样"学生 + 他的选课"常在同一个节点,查询不用跨节点。 - 混合分片(Hybrid Fragmentation):先水平再垂直(或反之)。例:全校学生先按学院水平切成片,再对"计算机学院片"按列切出"成绩片"。
分片正确性三条规则 ⭐
切完必须能拼回去、不能切丢、不能切重,三条规则是判断标准:
- 完备性(Completeness):全局关系的所有数据都必须被分到某个片断,不能遗漏。例:学生表 1000 行,各水平片断行数相加必须恰好等于 1000。
- 可重构性(Reconstructability):所有片断能拼回原关系。水平片断用并(UNION)——把各片行拼起来就是原表;垂直片断用连接(JOIN)——按公共主键把各列拼回完整表。
- 不相交性(Disjointness):片断之间互不重叠。水平片断要求"同一条记录不出现在两个片断里";垂直片断要求"除主键外,属性列不重复出现",否则列会重复存储。
💡 记忆口诀:完备性——不丢;可重构性——能拼;不相交性——不重。
⚠️ 常见错误
- 垂直分片忘了保留主键:切成
(姓名,学院)和(成绩),没有公共列,用 JOIN 无法重构。 - 水平分片的切分条件重叠:如"学院='计算机' 或 学号<1000"与"学号>500"有交集,一条记录落进两片,违反不相交性。
- 三条规则只会背名字、说不出操作:完备性对应"数据无遗漏",可重构性对应"水平 UNION、垂直 JOIN",不相交性对应"不重叠"。
2.4 数据分布策略:片断放在哪里
公司档案室的四种摆法
公司有一批文件(片断),档案室有几个(节点),怎么摆?把所有文件塞进一个房间(集中式);按部门一人一个房间各管各的(分割式);每个房间都复印一份全套(全复制式);"常用文件每个房间都有一份,冷门档案只放一个房间"(混合式)。
四种策略与读写开销
- 集中式(Centralized):所有片断放在一个节点。场景:数据量小、读写都在一个站点、不需容错的小系统。读/写:本地进行,快——但没有分布式收益,本质是"换个名字的集中式库"。
- 分割式(Partitioned):每个片断恰好放一个不同节点,不复制。场景:数据按地域或业务划分,如银行按省存放本地账目。读:只涉及本节点片断时快;跨片查询(如统计全国)要把多地数据搬到一处合并,开销大。写:本片内快;跨片事务(如转账跨省)需多节点协调,开销大。
- 全复制式(Fully Replicated):每个节点都放一份完整副本。场景:读极多、写极少的静态数据,如商品目录、全局配置表。读:本地读,最快。写:每改一次所有副本都要同步,随节点数线性增长,写频繁时系统被拖垮。
- 混合式(Hybrid):部分片断复制、部分片断分割。场景:绝大多数真实系统,如热门商品信息各地有副本、冷门历史订单只放一个节点,兼顾读与写。
💡 记忆口诀:读多用复制,写多用分割——复制牺牲写换读,分割牺牲跨片查询换本片读写。
⚠️ 常见错误
- 全复制式的读写开销记反:复制越多读越方便、写越累。
- 混淆"集中式"与"分割式":集中式所有片断在一点;分割式每个节点各放不同片断。
- 选策略只盯着读:给频繁更新的表配全复制,每次写都要全网同步,写性能会灾难性下降。
2.5 CAP 定理 ⭐
一群靠电话同步的朋友
想象你和三个朋友约定"随时同步手头的账目"。某天通信线路断了(网络分区)。这时来了一个新请求,你有两个选择:A——先按本地数据回答(有响应,但可能和朋友不一致);C——拒绝回答,等线路恢复、确认一致了再回应。两个都想做到?不可能——分区期间无法既"立刻回答"又"和朋友完全一致"。这就是 CAP 的核心困境。
三个字母
- C(Consistency,一致性):所有节点同一时刻看到相同数据,任何读都返回最近一次写入后的值。
- A(Availability,可用性):每个请求都能在合理时间内得到响应——注意,是"有响应",不承诺数据是最新的。
- P(Partition Tolerance,分区容错性):即使节点间网络发生分区(通信中断),系统仍能继续运行。
三选二,但 P 绕不过
CAP 说分布式系统最多同时满足其中两项。更关键的是——网络分区无法避免(机器会宕、线路会断),所以 P 必须保留,真正的选择只剩 C 和 A:
- CP(保一致、牺牲可用):例——银行账本。转账时无法确认两个账户余额是否一致,宁可拒绝请求,也绝不返回一笔可能算错的账。
- AP(保可用、接受短暂不一致):例——缓存、购物车。网络抖动时先返回本地缓存,用户照常下单,稍后后台再同步。
- CA(无分区时):单机数据库不涉及网络分区,天然是 CA——但它不是分布式。
💡 记忆口诀:P 绕不过,C/A 二选一;银行要 C,缓存要 A。
⚠️ 常见错误
- 把"三选二"理解成随便挑两个:分布式里 P 无法避免、必须保留,实际只在 C 和 A 之间选——"CA"在联网场景下不存在。
- 混淆"可用性"和"一致性":A 保证"有响应",C 保证"响应的是最新且正确的数据"——一个是"有没有",一个是"对不对"。
- 以为 CAP 是"三者同时最优":CAP 说的是权衡,不存在既完全一致、又永远可用、还能抗分区的"全能系统"。
2.6 分布式查询处理 ⭐
一张跨分店的订单查询单
总公司要"查全国所有分店中金额超过一万的订单"。你在任意一家分店敲下这条 SQL,流程就像大公司内部协作:总台拆解需求(查询分解)、确认哪个分店有数据(数据定位)、各分店自己优化执行(局部优化)、最后并行干活汇总(全局执行)。
五个步骤(文字推演一个跨节点查询)
全局查询 → 查询分解 → 数据定位 → 局部优化 → 全局执行
设 学生(学号,姓名,学院,成绩) 按学院水平分片:节点 1 存 计算机学院,节点 2 存 软件学院。用户在节点 1 提交:
查询:
SELECT 学号,姓名 FROM 学生 WHERE 学院='计算机' AND 成绩>=90
- 全局查询(Global Query):用户在任意节点提交 SQL,看到的是全局逻辑表
学生,无需知道它分了几片、放在哪。 - 查询分解(Query Decomposition):把 SQL 改写成等价的关系代数表达式,还不涉及数据位置:
σ(学院='计算机' ∧ 成绩>=90)(学生),纯粹是"把话翻译成标准算式"。 - 数据定位(Data Localization):按分片与分配模式,把
学生替换成具体片断:σ(学院='计算机' ∧ 成绩>=90)(学生₁ ∪ 学生₂)。此时做片断剪枝(fragment pruning):条件学院='计算机'正好命中节点 1 的片断,节点 2 根本不用参与,省掉一次跨节点通信。 - 局部优化(Local Optimization):节点 1 拿到自己的那部分表达式,利用本地索引、统计信息选出代价最低的执行计划(如先按
成绩索引过滤再投影)。 - 全局执行(Global Execution):各相关节点并行执行局部计划,结果经网络传回提交节点合并。本例只在节点 1 执行并返回,几乎零跨节点代价。
再看一个必须跨节点的例子:若查询是"所有学院中成绩≥90的学生",两片都有数据,则节点 1、节点 2 并行执行各自的局部查询,结果传回后做并(UNION) 合并再返回。并行是性能来源,合并与传输是网络开销所在。
⚠️ 常见错误
- 把"查询分解"和"数据定位"合并成一步:分解把 SQL 译成代数式(不关心数据在哪),定位把代数式映射到具体节点(开始关心数据在哪)。
- 忘记用分片条件做剪枝:上例只查计算机学院,若不剪枝,会把节点 2 的软件学院数据也搬过来合并,白白增加网络开销。
- 以为"局部优化"发生在全局层面:局部优化是各节点对自己那份表达式独立做,全局层只负责分发、合并。
2.7 分布式事务与两阶段提交(2PC)⭐
一次全员到齐才能交的课程作业
小组作业要求:全组所有人的部分都交齐,这次作业才算数。组长(协调者)逐个问:"你的部分做好了吗?"(阶段一:准备)。若每个人都说"做好了"(全部就绪),组长宣布"交!"(阶段二:提交);只要有一个人说"没做好",组长宣布"全组作废"(阶段二:回滚)。要么全交,要么全不交——这就是分布式事务要保证的"原子性"。
本地事务 vs 分布式事务
- 本地事务(Local Transaction):只在一个节点上执行,原子性、一致性由该节点自己的日志和锁机制保证,不用和别的节点商量。
- 分布式事务(Distributed Transaction):一个事务的操作分散在多个节点上执行(如转账:借记在 A 节点、贷记在 B 节点)。单靠各节点本地机制不够,必须由协议协调,保证"要么全提交、要么全回滚"。这个经典协议就是两阶段提交。
两阶段提交(2PC)分步推演 ⭐
角色:1 个协调者(Coordinator,事务发起节点)+ n 个参与者(Participants,事务涉及的各节点)。
阶段一:准备(Prepare)
- 协调者向所有参与者发送"准备提交(Prepare to commit)"消息。
- 每个参与者执行属于自己的写操作(写入本地、记入日志),但不真正提交。
- 每个参与者投票:可以提交 → 就绪(Ready);出了差错 → 放弃(Abort)。
阶段二:提交/回滚(Commit/Abort)
- 协调者收集所有投票:
- 全部"就绪" → 广播"提交(Commit)",各参与者正式提交,事务完成。
- 任一"放弃" → 广播"回滚(Abort)",各参与者撤销已做操作。
- 协调者先把决策写入日志再广播,防止决策后宕机丢记忆。
2PC 的阻塞问题(Blocking Problem) ⭐:2PC 的最大软肋。若协调者在阶段二发出提交消息后、参与者还没收到前宕机,参与者无法单方面决定提交还是回滚,只能一直等待恢复,事务被挂起——这就是阻塞。改进方案是三阶段提交(3PC),在阶段一、二之间加"预提交(Pre-commit)"缓冲,缩小阻塞窗口,但协议更复杂。
⚠️ 常见错误
- 以为"有一个参与者就绪就能提交":2PC 要求所有参与者都回"就绪"才提交,任一放弃就全体回滚——"全部"和"任一"最容易记反。
- 把"准备"阶段当成"已经提交":阶段一只写日志、做准备,数据还没真正提交;提交发生在阶段二收到提交消息之后。
- 以为 2PC 解决了分布式事务的所有问题:它解决了原子性,但没解决阻塞——协调者故障时参与者会被挂起,只能等待恢复。
🧠 记忆口诀
- 分布式定义:物理分散,逻辑统一。
- 三层模式:全局模式(长什么样)→ 分片模式(怎么切)→ 分配模式(放哪里)。
- 分片正确性:完备不丢、可重构能拼、不相交不重。
- 分布策略:集、割、复、混;读多用复制,写多用分割。
- CAP:P 绕不过,C/A 二选一;银行要 C,缓存要 A。
- 查询五步:全局查询 → 查询分解 → 数据定位 → 局部优化 → 全局执行。
- 2PC:先准备,再表决;全就绪才提交,一反对就回滚。
⭐ 考点清单
- 分布式数据库的定义:"物理分散、逻辑统一"。
- 与集中式对比:优点(高可用、可扩展、局部自治)与挑战(一致性、网络开销、复杂度)。
- 三层模式映射:全局→分片→分配;客户端/服务器与对等(P2P)模式的区别。
- 水平分片(按行)、垂直分片(按列,留主键)、导出分片(跟随别的表)、混合分片。
- 分片正确性三规则:完备性、可重构性(水平 UNION、垂直 JOIN)、不相交性。
- 四种分布策略的读写开销:集中式、分割式、全复制式(读快写慢)、混合式。
- CAP:C / A / P 含义;P 不可绕;银行(CP)与缓存(AP)的权衡。
- 分布式查询五步流程与"片断剪枝";2PC 两阶段、阻塞问题;分布式与本地事务的区别。
📌 中英术语表
| 中文 | English |
|---|---|
| 分布式数据库 | distributed database |
| 分布式数据库管理系统 | DDBMS |
| 位置透明性 | location transparency |
| 全局模式 | global schema |
| 分片模式 | fragmentation schema |
| 分配模式 | allocation schema |
| 水平分片 | horizontal fragmentation |
| 垂直分片 | vertical fragmentation |
| 导出分片 | derived fragmentation |
| 混合分片 | hybrid fragmentation |
| 完备性 | completeness |
| 可重构性 | reconstructability |
| 不相交性 | disjointness |
| 集中式 / 分割式 | centralized / partitioned |
| 全复制式 / 混合式 | fully replicated / hybrid |
| 一致性 | consistency |
| 可用性 | availability |
| 分区容错性 | partition tolerance |
| 查询分解 | query decomposition |
| 数据定位 | data localization |
| 局部优化 | local optimization |
| 全局执行 | global execution |
| 片断剪枝 | fragment pruning |
| 分布式事务 | distributed transaction |
| 本地事务 | local transaction |
| 两阶段提交 | two-phase commit (2PC) |
| 协调者 / 参与者 | coordinator / participant |
| 阻塞问题 | blocking problem |
| 三阶段提交 | three-phase commit (3PC) |