【问题标题】:Sync MySQL and MSSQL databases through windows service通过windows服务同步MySQL和MSSQL数据库
【发布时间】:2014-06-20 01:33:42
【问题描述】:

我必须同步两个数据库的 2 个表,其中一个是 MSSQL,另一个是 MySQL。我必须通过 Windows 服务来做到这一点。我目前已经创建了一个 Windows 服务,我目前添加到服务中的是:从 MySQL 数据库中获取数据并将其插入到数据适配器中,我计划使用插入通过事务将数据从该适配器移动到 MSSQL 数据库.你能告诉我什么是解决这个问题的最佳方法吗?如果我现在正在做的事情是在正确的轨道上,我第一次做这样的事情。

【问题讨论】:

  • 您是否尝试过使用 SSIS 将 MySQL 等异构数据库同步到 MSSQL?这可能会完成您的工作。

标签: c# mysql sql sql-server windows-services


【解决方案1】:

嗯,可能有几种方法可以解决这个问题。您没有提到表的数量和大小、所需的同步频率,所以我的回答可能不是 100% 相关的。无论如何,我的建议是:

  1. 每个表都应该有额外的列 - SyncDate (TIMESTAMP),默认为空。
  2. 在 Windows 服务中实现的同步逻辑通过执行这样的查询定期检查每个表是否有要同步的数据(出于性能原因使用纯 IDataReader):

    从 SyncDate 为空的 TEST_TABLE 中选择 *

  3. 如果上述语句返回数据则:

    • 收集要插入的行包(例如 500 行)
    • 在目标数据库上开始事务并为收集的包执行插入语句(将列 SyncDate 的值设置为 DateTime.Now)
    • 当插入完成时,在源数据库中执行如下语句:

    UPDATE TEST_TABLE SET SyncDate = @DateTime.Now where ID_PRIMARY_KEY IN (IDENTIFIRES FROM PACKAGE)

    • 提交交易
    • 收集另一个包并重复算法,直到 DataReader 提供数据
  4. 上述算法应适用于两个数据库

  5. 可能您的数据库有外键,因此您必须记住,依赖表应按有效顺序同步
  6. 只要有可能,您就可以从多线程中受益

【讨论】:

  • 一点。两个数据库中的表应该在代码中进行比较,否则会插入我们不想要的重复记录。或许你可以对这部分有所了解?
  • 冗余有时并没有那么糟糕,但当然它取决于商业模式,通常最好避免它。为此,除了比较记录之外,我没有看到任何其他方法,但是通过执行带有表中所有列的 where 子句的查询来做到这一点听起来并不完美。更智能的方法是附加列 RecordHash,其中包含在插入期间生成的唯一标识符,该标识符基于除 SyncDate 和 Primary Key Id 之外的所有其他列的值。在插入数据之前有这样的结构做目标表你必须执行查询来检查哪些数据是新的。
【解决方案2】:

对于此类工作,SQL Server 集成服务是最佳选择。

SSIS 用于提取、转换和加载数据。 (ETL过程)

您为数据的每个转换步骤设计一个工作流,从 MySQL 到 MSSQL。

然后您创建一个作业并配置它的计划,它将由 SQL Server 执行。

无需从头开始开发且难以维护。

【讨论】:

    【解决方案3】:

    如果您将 mySql 数据库添加为链接服务器 (sp_addlinkedserver),那么我认为您可以在 MS SQL 数据库的存储过程中执行以下操作:

     insert table1(col1) 
     select col1 
     from openquery('MySqlLinkedDb','select col1 from mySqlDb.dbo.table2')
    

    【讨论】:

    • 您不要通过 C# 添加链接服务器,而是通过 Sql server Management Studio 来添加。看看这个:technet.microsoft.com/en-us/library/ms190479.aspx。链接服务器名称相当于上面的 MySqlLinkedDb。添加后,您可以检查通过 select * from sys.servers 链接的服务器列表。
    • 我正在寻找使用 Microsoft Sync Framework 的解决方案。也许你确实有一些经验?
    【解决方案4】:

    如果您必须通过 Windows 服务执行此操作,我很好奇您是如何从 MySQL 接收数据的?是什么发起了对服务的调用,传入的数据是什么形式的?您是在进行更改还是对数据进行了几次刷新?

    例如,如果您收到 DataTable 或某种其他类型的 IEnumerable 并对其进行完全刷新,则可以使用 SqlBulkCopy.WriteToServer()。那将是最快和最有效的。

    汤姆

    【讨论】:

      【解决方案5】:

      如果您已经准备好将 MySQL 数据移动到 SQL。我建议您将它们放在单独的表上并发出合并命令来合并数据。确保标记已更新的数据,以便您现在可以将它们取回并推送到 MySQL:

      MERGE TableFromMySQL AS TARGET USING TableFromSQL AS SOURCE
          ON (TARGET.PrimaryKey = SOURCE.PrimaryKey)
               WHEN Matched AND (TARGET.Field1 <> SOURCE.Field1
                  OR TARGET.Field2 <> SOURCE.Field2
                  OR .. put more field comparison here that you want to sync
               THEN
                  UPDATE
                  SET TARGET.Field1 = SOURCE.Field1,
                      TARGET.Field2 = SOURCE.Field2,
                      //flag the target field as updated
                      TARGET.IsUpdated = 1,
                      TARGET.LastUpdatedOn = GETDATE()
                  WHEN Not Matched 
                  THEN
          INSERT(PrimaryKey, Field1, Field2, IsUpdated, LastUpdatedOn)
          VALUES(SOURCE.PrimaryKey, SOURCE.Field1, SOURCE.Field2, 1, GETDATE());
      

      此时,您现在可以使用 IsUpdated = 1 查询 MySQL 表并将所有值推送到 MYSQL 数据库。我希望这会有所帮助。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-12-14
        • 1970-01-01
        • 1970-01-01
        • 2013-06-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-05-09
        相关资源
        最近更新 更多