3. 基于领域边界的数据库拆分原则

在微服务架构中,数据库不再是单一的数据孤岛,而是每个限界上下文(Bounded Context)的私有持久化边界。错误的数据库拆分会导致跨服务查询爆炸、分布式事务蔓延,最终使系统退化回单体耦合状态。本章围绕“限界上下文”这一核心,给出数据库拆分的具体原则、策略以及事务边界与一致性模型的选择依据。

3.1 根据限界上下文划分数据库

限界上下文是领域驱动设计(DDD)中定义模型边界的核心模式。每个限界上下文拥有独立的业务语言、业务规则和数据模型。数据库拆分的第一原则就是:一个限界上下文对应一个独立的数据库实例(或 Schema)。

限界上下文 业务职责 数据库归属 数据访问模式
用户上下文 注册、登录、权限 user_db 高读、低写、缓存优先
订单上下文 下单、支付、退款 order_db 高写、事务强一致
库存上下文 库存扣减、补货 inventory_db 高并发写、乐观锁
商品上下文 商品信息、分类、搜索 product_db 高读、写少、ES 辅助
支付上下文 支付渠道、对账 payment_db 最终一致性、异步
实践要点:不要因为“数据关联查询方便”而合并两个限界上下文的数据库。跨上下文的数据查询应通过 API 编排或 CQRS 模式解决,而非数据库 JOIN。
限界上下文与数据库拆分映射 用户上下文 注册 / 登录 / 权限 订单上下文 下单 / 支付 / 退款 库存上下文 扣减 / 补货 商品上下文 信息 / 搜索 user_db order_db inventory_db product_db 核心原则: • 每个限界上下文拥有独立的数据库实例,禁止跨上下文直接访问数据库。 • 跨上下文的数据查询通过 API 编排、事件驱动或 CQRS 视图实现。 • 数据库拆分后,每个微服务团队拥有独立的数据 Schema 变更权,互不阻塞。

3.2 数据库拆分策略

根据业务规模和数据量级,数据库拆分可分为三个层次:单库、分库、分表。选择哪种策略取决于数据量、并发量以及业务增长预期。

3.2.1 单库模式

适用于小型项目或早期阶段。一个限界上下文对应一个数据库实例,内部使用多张表组织数据。优点是架构简单、事务支持完整;缺点是单库存在性能上限,无法水平扩展。

3.2.2 分库模式

当单库无法满足并发或存储需求时,将一个限界上下文的数据水平拆分到多个数据库实例中。分库键(Sharding Key)的选择至关重要,通常使用用户 ID、订单 ID 等业务主键。

3.2.3 分表模式

当单表数据量过大(如超过千万行)时,将一张表按时间、哈希或范围拆分为多张物理表。分表通常与分库组合使用,形成“分库分表”方案。

拆分策略 适用场景 优点 缺点
单库 数据量 < 100GB,QPS < 2000 事务完整、开发简单 无法水平扩展
分库 数据量 > 100GB,QPS > 5000 水平扩展、隔离性好 跨库查询复杂、分布式事务
分表 单表行数 > 1000 万 降低单表压力、提升查询性能 跨表聚合查询困难
分库+分表 海量数据 + 超高并发 极致扩展能力 运维复杂、路由逻辑重
避坑提示:不要过早引入分库分表。在单库模式下通过索引优化、缓存、读写分离等手段通常能支撑千万级日活。分库分表带来的分布式事务和查询复杂度,往往比性能收益更早成为瓶颈。
数据库拆分策略决策流程 评估数据量与并发 单库够用? 单库模式 分库分表? 分库模式 分表模式

3.3 事务边界与一致性模型

数据库拆分后,事务边界从单库本地事务变为跨库分布式事务。一致性模型的选择直接影响系统可用性和数据正确性。

3.3.1 事务边界划分原则

  • 强一致性事务:仅在一个限界上下文内部使用,通过本地 ACID 事务保证。
  • 最终一致性事务:跨限界上下文的操作,通过 Saga、事件驱动或 TCC 模式实现。
  • 事务边界与聚合根对齐:一个事务只修改一个聚合根,避免跨聚合的事务。

3.3.2 一致性模型对比

一致性模型 适用场景 实现方式 性能影响
强一致性 单库、单聚合根操作 本地事务(ACID) 低
最终一致性 跨上下文、异步操作 事件驱动 + 补偿 中
弱一致性 读多写少、可容忍延迟 缓存 + 异步同步 高
可串行化快照隔离 高并发写、冲突少 乐观锁 + 重试 中高
Go 微服务实践建议:在 Go 中实现 Saga 模式时,优先使用 github.com/uber-go/cadence 或 github.com/ThreeDotsLabs/watermill 等成熟框架,避免手写分布式事务协调逻辑。每个 Saga 步骤应幂等,补偿操作必须可重入。

3.3.3 一致性模型选择矩阵

根据业务对一致性的容忍度,选择合适模型:

  • 资金类操作(支付、转账):强一致性或 Saga 严格顺序执行。
  • 库存扣减:最终一致性 + 乐观锁,允许超卖后补偿。
  • 用户资料更新:最终一致性,缓存异步刷新。
  • 日志/审计:弱一致性,批量写入。
关键提醒:不要试图用分布式事务模拟单库 ACID。跨库的 2PC(两阶段提交)在微服务环境中几乎不可用,因为它会阻塞资源、降低可用性。Saga 模式才是跨限界上下文事务的正确选择。

3.4 本章小结

基于领域边界的数据库拆分,核心在于“限界上下文即数据库边界”。拆分策略从单库到分库分表逐级演进,事务边界与一致性模型的选择必须与业务容忍度对齐。记住三条铁律:

  1. 一个限界上下文一个数据库,禁止跨上下文直接访问。
  2. 拆分策略按需演进,不要为未来过度设计。
  3. 事务边界与聚合根对齐,跨上下文用 Saga 保证最终一致性。