在 SQL Server 中同步两个数据库

Ema*_*khi 17 sql-server data-synchronization

我有两个 SQL Server 数据库。一个是客户端(Windows 应用程序),第二个是在服务器上。我想每隔一段时间(例如每 2 分钟!)同步这两个数据库。

我已经阅读了不同的同步方式,如复制、时间戳、使用触发器的日志表、Microsoft 同步框架等。

实际上,我不喜欢使用可能是黑匣子(如复制)的同步方法,因为我不希望在更新 SQL Server 特定表并将它们与服务器同步时被阻止。

  1. 你认为我应该在这种情况下使用哪种方法?请记住,每隔几分钟我必须从客户端向服务器发送几个表更改,并从服务器获取两个表更改。

  2. 我发现了一种奇怪但新颖的方法。是否有可能我在客户端记录所有已执行的(对于特定的首选)存储过程,并将它们与它们的参数一起发送.sql到服务器并在那里执行它们?同样的事情也会发生在服务器上并发送到客户端。你认为这是一个简单而有用的方法吗?

  3. 如果可以,请给我建议任何有用的方法。非常感谢。

编辑:请记住,这是一个实时同步,这使它很特别。这意味着当客户端用户使用该表时,与服务器的同步过程必须每隔几分钟发生一次,因此不必锁定任何表。

Ion*_*nic 14

好吧,我可能不明白,但我试着回答它。

你说你需要一个经常运行的高性能解决方案(至少 2 分钟),并且你需要一个很好的方法,它应该是快速而不锁定的。但是你不想要一个黑盒系统。

您不再尝试重新发明轮子并构建自己的解决方案,而不是用于数百万次安装并取得良好效果的黑盒系统?嗯,听起来有点奇怪。

其实这些都是我的建议。

  1. 即使你说你不会使用它也复制。这是您可以使用的最简单和最好的解决方案。复制易于设置,复制速度快,您不必再次发明轮子。如果您只是对锁定感到奇怪,您可以尝试ISOLATION LEVELREAD_COMMITTED_SNAPSHOT. 您可以在此处阅读更多相关信息。这将使用您的 tempdb 的一部分,但您的表始终是可读写的,并且复制可以在后台工作。

请参阅下面的示例:

ALTER DATABASE yourDatabase SET ALLOW_SNAPSHOT_ISOLATION ON
ALTER DATABASE yourDatabase SET READ_COMMITTED_SNAPSHOT ON
Run Code Online (Sandbox Code Playgroud)
  1. CDC(变更数据捕获)也可以是一个解决方案。但是通过这种方式,您需要自己构建几乎所有内容。而且我已经做出了CDC在某些情况下可能是脆弱的事情的经验。CDC将捕获监视表上的所有数据(您需要手动指定每个监视表)。之后,您将获得INSERT,UPDATE或之后的值和之前的值DELETECDC将保留这些信息一段时间(您可以自行指定)。该方法可能是CDC在您需要监视的某些表上使用并手动将这些更改复制到其他数据库。顺便说一句,CDC也在幕后使用 SQL Server 复制。;-) 你可以在这里阅读更多关于它的信息

警告:CDC不会意识到DDL-changes。这意味着,如果您更改表并添加新列,CDC将监视该表但忽略对新列的所有更改。实际上它只记录NULL为之前的值和之后的值。您需要在DDL-Changes 到监视表后重新初始化它。

  1. 您上面描述的方式类似于使用 SQL Server Profiler 捕获工作负载,然后在另一个数据库上再次运行它以进行某些基准测试。那么它可以工作。但副作用太多的事实对我来说有点太重了。如果您在客户端上捕获过程调用,您会怎么做。之后在您的主数据库上运行相同的命令,因为它不同步?该过程可能会运行,但它可能会删除/更新/插入客户端中不存在的行。或者你如何用一个原则处理多个客户。我觉得这太棘手了。在最坏的情况下,您可能会破坏您的诚信。
  2. 另一个想法可能是基于应用程序或使用触发器。取决于您要同步的表数量。您可以将所有更改写入单独的临时表,并在所有 x 分钟内运行 SQL Server 代理作业以将临时表中的这些行与您的主服务器同步。但是,如果您尝试同步(例如)150 个表,这可能有点繁重。你会有很大的开销。

嗯,这些是我的 2 美分。希望您有一个很好的概述,也许您找到了一种适合您的解决方案。


Voj*_*nal 9

我将尝试在这里列举一些我认为的优点和缺点的选项:

  1. SQL Server 复制- 这是用于此任务的最佳和最优化的本机 SQL Server 工具。但是有几个问题: a.对于您的所有客户端,无论它们是否是 SQL Express 数据库,您都需要 SQL Server CAL 许可证。使用按处理器许可可以避免这种情况。您不能按照此处同步 SQL CE 客户端。C。SQL Express 或 LocalDB不能充当发​​布者或分发者,因此您对客户端复制过程的控制较少。
  2. Microsoft Sync Framework - 在我看来更适合较小的移动应用程序数据库。它向您的数据库添加了相当多的表,而且效率不如复制。由于它是作为组件在 SQL Server 之外实现的,因此配置起来会更加困难。我没有使用它的经验,只是尝试过并决定不使用它。

  3. 数据库更改跟踪。它是一个内置的 SQL Server 功能,可为您进行更改跟踪,包括插入、更新和删除。其他所有事情,例如发送和应用更改、解决冲突等,您都必须自己编写代码。

  4. Rowversion(时间戳)列如果您禁止所有删除(不同步已删除的记录) - 您可以仅基于 rowversion 信息实施您自己的解决方案。SQL Server 复制也使用 Rowversion 列,因此您无论如何都需要添加它们。
  5. Ionic 的回答中提到的 CDC - 我没有使用它的经验,因为它仅在企业版或开发版中可用。

  6. 使用您自己的技巧记录执行的存储过程 - 很大程度上取决于您的数据库应用程序的性质。但是当程序几乎没有什么不同时,数据就会变得一团糟。你会如何处理冲突?

从您的问题来看,您似乎只需要同步几个表而不是整个大型数据库。为此,您应该比问题中指定的更详细地分析您的需求,例如:

  • 删除会发生吗,然后会发生什么?
  • 冲突会不会发生,如何预防以及如何解决?
  • 我将如何处理表结构更改?
  • ...

如果您最终发现删除和冲突不是您的问题,并且您的结构不会发生很大变化,您可以考虑编写自己的逻辑,但它可以轻松增长到 1000 行代码。