使用 C# 同步不同数据库中的两个表

本文关键字:两个 同步 数据库 使用 | 更新日期: 2023-09-27 17:56:43

我有一个远程Postgresql DB,其中包含一个包含信息(只有几列而不是整个表)的表(我不能更改),我想用一个表(我可以更改)同步到本地SQL Server 2008 Express数据库。

现在我正在寻找一种有效的方法来做到这一点。由于同步将每 ~5 分钟运行一次,每次重新加载整个表会产生大量不必要的流量,我试图避免。

我想过保存最新的ID,只是抓取所有较新的ID,但旧数据可能会(不太可能,但仍然有可能)被更改。只是这样,我会错过更改后的数据。

同步将由与本地 SQL Server 在同一台计算机上运行的 C# 程序完成。

使用 C# 同步不同数据库中的两个表

这个问题有两种解决方案。 您可以尝试变得聪明,只传输更改 - 但这需要在源数据库上进行一些集成;我相信您的数据库管理员可以帮助您 - 可能是跟踪所有接触的行的触发器(例如使用源表的主键)。此解决方案的扩展性相当好,但更复杂。 我认为您应该考虑第二种选择:简单的蛮力。

从声音上看,您的整个桌子可以舒适地容纳 100MB。 这只是不多的数据。 假设您可以获得 10MB/s 的传输速率(这根本不是很古怪),您可以在 10 秒内传输所有内容。 如果如您所说,您只需要几列,则总数据传输可能会少得多。 每五分钟使用 10 秒的数字,这将在 3% 的负载量级上保持数据最新 - 对于源数据库来说,这是一个微不足道的查询,可能不会造成太大负载,特别是因为它将全部缓存在内存中,因为数据集太小了。

看看SqlBulkCopy. 本文(使用 SqlBulkCopy 的 Transderring 数据)是使用它将数据从一个数据库复制到下一个数据库的示例。 源数据读取器可以是任何东西;例如,我用它来插入来自对象的计算数据,但一个特别简单的情况是 DbDataReader,您可以从 Postgresql 获得 select 语句。

不幸的是,默认选项不是太出色,因此您可能需要指定对您有用的SqlBulkCopyOptions。 TableLock可能不是一个坏的。 此外,如果您并行执行此操作(即将多个批量插入到一个表中),请注意索引(这可能会导致死锁)。 如果使用批量副本批处理大小,则可以优化吞吐量和内存使用量之间的权衡,尽管默认值可能工作正常。

从概念上讲,我会这样做:

  • 打开与源数据库和目标数据库的连接(使用 using
  • 在目标数据库连接上启动SqlTransaction
  • 删除目标表中的所有行。
  • 从源到目标的批量复制(不要忘记传递事务)

这样,您将以原子方式更新目标表。

我不确定您要做什么,但如果这是某种形式的缓存,请考虑完全取消目标SQL服务器,并将数据作为对象数组保留在内存中。 内存中对只读数据的访问速度非常快,并且您的数据集可以轻松放入内存中。