共享数据库集成

多个服务或系统直接读写同一数据库的集成方式;短期省事,长期锁死表结构、绕过业务规则并制造隐性耦合,常见替代方案是接口或事件集成。

什么是共享数据库集成

共享数据库集成指多个服务或系统直接读写同一个数据库来完成协作。它短期省事:不用定义接口、不用处理消息,加一张表就能联调。长期代价是表结构被多方锁死、业务规则被路径绕过、故障互相传导,最终演化成最难拆的耦合。识别信号很直接:发布会要求「先改库再通知大家」。

基本信息

典型问题表结构变更牵连多方;业务校验被绕过;故障相互影响
识别信号出现「先改库再通知」的发布流程;同表被多个服务写入
替代方向暴露 API 或发布事件;过渡期用数据同步加契约约束
迁移原则按消费方逐一切换,先建接口与双写,再核对一致性,最后收回直连权限

典型使用场景

  • 遗留系统并行期:短期内无法拆分,用共享库维持协作但需明确约束
  • 报表与查询:只读消费方通过只读副本或数据同步读取,而非直连主库
  • 过渡迁移:为直连方提供 API 或事件通道,双写期间核对一致性
  • 数据归档:把历史数据同步到独立分析库,减轻在线库压力
  • 跨系统对账:通过同步通道交换数据,避免直接写对方表
  • 权限收敛:确认无直连流量后,回收数据库账号与网络权限

退共享库的迁移步骤

步骤动作完成判定
建接口为直连方提供 API 或事件通道所有消费方都有可用替代接口
双写核对过渡期双写,定时比对差异差异率稳定在阈值内
逐方切换按消费方逐个切换并观察切换后无回退,监控正常
收回权限确认无直连流量后回收账号数据库账号与网络策略已收敛

双写核对与收敛(示意)

双写核对与收敛(示意)
-- 过渡期:新路径写接口,同时比对旧表与新表的一致性
-- 1) 抽样比对关键字段
SELECT a.id, a.status AS old_status, b.status AS new_status
FROM legacy_orders a JOIN new_orders b ON a.id = b.id
WHERE a.updated_at > NOW() - INTERVAL 1 DAY
  AND (a.status <> b.status OR a.amount <> b.amount);
-- 2) 差异率纳入监控,持续为零并观察一个完整业务周期后,
--    通知消费方切换,最后回收数据库直连账号
共享库最危险的不是性能而是规则绕行:直连方能跳过业务校验直接改数据,导致口径分裂,事后极难对账。
短期保留共享库并非不可接受,但必须写清约束:哪些表允许写、谁负责变更评审、退出时间点是什么。

易错点

  • 多方直连同一库并各自实现业务规则,口径分裂,对账无法收敛
  • 表结构变更未经协调,发布当晚互相影响,回滚互相牵制
  • 直连方长期存在无人清理,共享库成为永久性耦合点
  • 缺少双写与差异核对,切换时才发现数据对不上

数据来源与参考

  • microservices.io:Shared Database
  • 《Building Microservices(第 2 版)》(Newman)
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌