异构数据库同步是很多多系统协作场景下的常见需求,不同业务系统可能使用SQL Server、MySQL、Oracle等不同类型的数据库,需要在数据发生变更时自动将变更同步到其他系统的数据库中。通过SQL Server的触发器和链接服务器功能,可以实现轻量级的自动同步逻辑,不需要额外引入复杂的中间件。

核心实现原理
整个方案的核心逻辑分为两部分:首先通过链接服务器建立SQL Server到目标异构数据库的连接通道,让SQL Server可以跨数据库执行操作;然后在源数据库的表上创建触发器,当表发生INSERT、UPDATE、DELETE操作时,触发器自动通过链接服务器将变更后的数据同步到目标数据库对应的表中。
第一步:配置链接服务器
链接服务器是SQL Server访问外部数据源的桥梁,这里以SQL Server连接MySQL为例,需要先安装MySQL的ODBC驱动,然后在SQL Server中配置链接服务器:
-- 创建链接服务器,假设目标MySQL数据库地址为192.168.0.100,端口3306,数据库名test_db
EXEC sp_addlinkedserver
@server = 'MYSQL_LINK', -- 链接服务器名称,后续触发器中会用到
@srvproduct = 'MySQL',
@provider = 'MSDASQL',
@datasrc = 'MySQL_ODBC_8.0' -- 之前安装的ODBC数据源名称
-- 配置链接服务器的登录映射,设置访问目标MySQL的用户名和密码
EXEC sp_addlinkedsrvlogin
@rmtsrvname = 'MYSQL_LINK',
@useself = 'false',
@locallogin = NULL,
@rmtuser = 'mysql_user', -- MySQL用户名
@rmtpassword = 'mysql_pwd' -- MySQL密码
-- 测试链接服务器是否可用,查询目标MySQL的版本信息
SELECT * FROM OPENQUERY(MYSQL_LINK, 'SELECT VERSION() AS mysql_version')第二步:编写同步触发器
触发器需要覆盖数据的增删改三种操作,这里以同步用户表user_info为例,假设源表和目标表结构一致,都包含user_id、user_name、age三个字段:
-- 创建INSERT触发器,新增数据时同步到目标MySQL
CREATE TRIGGER trg_user_info_insert
ON user_info
AFTER INSERT
AS
BEGIN
-- 避免触发器递归执行
IF TRIGGER_NESTLEVEL() > 1 RETURN
-- 通过链接服务器插入数据到目标表
INSERT OPENQUERY(MYSQL_LINK, 'SELECT user_id, user_name, age FROM test_db.user_info')
SELECT user_id, user_name, age FROM inserted
END
-- 创建UPDATE触发器,修改数据时同步更新目标库
CREATE TRIGGER trg_user_info_update
ON user_info
AFTER UPDATE
AS
BEGIN
IF TRIGGER_NESTLEVEL() > 1 RETURN
-- 先更新目标表中对应数据
UPDATE t
SET t.user_name = i.user_name,
t.age = i.age
FROM OPENQUERY(MYSQL_LINK, 'SELECT user_id, user_name, age FROM test_db.user_info') t
INNER JOIN inserted i ON t.user_id = i.user_id
END
-- 创建DELETE触发器,删除数据时同步删除目标库数据
CREATE TRIGGER trg_user_info_delete
ON user_info
AFTER DELETE
AS
BEGIN
IF TRIGGER_NESTLEVEL() > 1 RETURN
-- 删除目标表中对应数据
DELETE t
FROM OPENQUERY(MYSQL_LINK, 'SELECT user_id, user_name, age FROM test_db.user_info') t
INNER JOIN deleted d ON t.user_id = d.user_id
END注意事项
- 不同异构数据库的SQL语法存在差异,使用
OPENQUERY执行远程查询时,需要遵循目标数据库的语法规则,比如MySQL的字符串拼接用CONCAT,而SQL Server用+。 - 触发器执行会占用源数据库的事务资源,如果同步的数据量较大或者目标库连接不稳定,可能会导致源库操作变慢,建议仅用于中小规模的数据同步场景。
- 如果目标表不存在对应字段,或者字段类型不兼容,同步操作会失败,需要提前保证源表和目标表的结构兼容性,必要时可以在触发器中做字段映射处理。
- 可以结合SQL Server的日志表记录同步失败的操作,方便后续排查问题,避免数据不一致。
适用场景
这种方案适合同步频率不高、数据量不大的场景,比如两个内部系统的少量基础数据同步,不需要额外部署同步中间件,维护成本较低。如果是高并发、大数据量的同步需求,建议使用专业的数据同步工具,避免触发器影响源数据库的正常业务操作。