修改后如何校验源表与目标表记录数一致性并实现跨库数据同步?
跨库父子表增量同步优化方案
你之前构想的两种方案在多关联表场景下确实存在性能差、代码冗余的问题,以下是三种更适配的处理方案:
方案1:基于时间戳/版本号的增量同步(推荐业务自研场景用)
- 给源库所有父子表新增两个通用字段:
last_updated(记录行最后修改时间,配置数据库自动更新触发器或者业务逻辑写入时自动刷新)、is_deleted(软删除标记,代替物理删除操作) - 同步时仅拉取源库中
last_updated大于上次同步时间的增量数据:- 父表:匹配GUID,目标库不存在则插入,已存在则直接覆盖更新,源库标记为软删的记录同步删除目标库对应行
- 子表:关联父表GUID,按同样的时间戳规则拉取增量更新,按顺序执行插入/更新/删除操作
- 优势:不需要全表比对数据,同步性能高,8张表可以抽象出通用同步逻辑,不需要逐表编写校验代码,维护成本低
方案2:用数据库原生同步能力(无代码开发场景用)
如果源库和目标库是同类型数据库,可以直接用数据库自带的同步功能,比如SQL Server的事务复制、MySQL的主从同步,只需要配置源库为发布端、目标库为订阅端,选择需要同步的父子表即可,数据库会自动完成全量+增量的数据同步,不需要自己编写业务代码处理关联关系和数据一致性。
- 优势:复用数据库原生一致性保障机制,同步延迟低,没有额外代码维护成本
方案3:通用MERGE语句模板(无法改表结构场景用)
如果不能修改源库表结构也无法用原生同步工具,可以用SQL标准MERGE语句代替原来的删了重插+UNION校验逻辑,单表同步可以抽象为统一模板,替换表名和字段即可:
MERGE TargetDb.dbo.Table1 AS TARGET USING SourceDb.dbo.Table1 AS SOURCE ON TARGET.GUID = SOURCE.GUID -- 源存在目标不存在:插入新记录 WHEN NOT MATCHED BY TARGET THEN INSERT (列1, 列2, 列3...) VALUES (SOURCE.列1, SOURCE.列2, SOURCE.列3...) -- 两边都存在:更新为源库最新值 WHEN MATCHED THEN UPDATE SET TARGET.列1 = SOURCE.列1, TARGET.列2 = SOURCE.列2, ... -- 目标存在源不存在:删除冗余记录 WHEN NOT MATCHED BY SOURCE THEN DELETE;
- 优势:单表逻辑统一,不需要单独做UNION数据一致性校验,语句为原子操作,不会出现删了之后插入失败的数据不一致问题,按父表先同步、子表后同步的顺序执行即可适配关联表场景
注意事项
- 同步操作要严格按照父表在前、子表在后的顺序执行,避免外键约束报错
- 单表数据量超过100万时建议按GUID或者主键范围分批执行同步,避免锁表影响源库业务
内容的提问来源于stack exchange,提问作者Robbie Robertson
相关产品推荐
相关产品推荐

