2013-01-31 104 views
2

我有一个远程Postgresql数据库与一个表(我不能改变),包含信息(只有几列不是整个表)我想同步到本地SQL Server 2008 Express数据库与表(我可以改变)。使用C#同步两个表在不同的数据库

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

我想过保存最新的ID,只是抓住所有更新的东西,但是有可能(不太可能,但仍有可能)旧数据被改变。就这样,我会错过修改后的数据。

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

+0

SQL 2008 Express是否带有SQL Server代理?如果是这样的话,你可以把它写成一个预定的作业,这将消除对c#应用程序的需求。此外,表中有多少行,因为它可能不是那么多的流量。被更改的数据需要可见,并且没有包含修改日期,哈希码等的数据的某种标记,这将是困难的。不确定SQL复制是否适用于不同的数据库提供者,但是如果它是另一种可以最小化流量的选项 – Charleh

+0

否Postgresql DB中的“LastModifiedTime”和“InsertTime”列? –

+0

不幸的是,Postgresql表没有日期/修改列,我不能添加它们:(据我所知,SQL复制只适用于SQL Server之间。此时表约有100k行 –

回答

2

有两个解决这个问题的方法。您可以尝试变得聪明,只能传输更改 - 但是要求在源数据库上进行一些整合;我确信你的数据库管理员可以帮助你 - 可能触发所有触及的行(例如使用源表的主键)。这个解决方案可以很好地扩展,但它更复杂。我想你应该看看第二个选择:简单的蛮力。

通过它的声音,你的整个桌子舒适地在100MB适合。这只是没有太多数据。假设你可以获得10MB/s的传输速率(这根本不是很古怪),你可以在10秒内传输所有内容。如果像你说的那样,你只需要几列,那么总的数据传输可能会少得多。以每10分钟10秒的数字来计算,这将会是3%负载的数量,以保持数据更新 - 这对于源数据库来说是一个微不足道的查询,可能不会导致太多负载,因为数据集非常小,所以都会被缓存在内存中。

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

不幸的是,默认选项不太精彩,所以你可能想指定SqlBulkCopyOptions对你有用。 TableLock可能不是一个坏的。另外,如果你并行地执行这个操作(即将多个批量插入到一个表中),请注意索引(这可能导致死锁)。如果使用批量复制批量大小,则可以优化吞吐量和内存使用量之间的权衡,尽管默认值可能正常工作。

概念,那么我这样做:

  • 打开你的源和目标数据库的连接(使用using
  • 目标数据库连接上启动SqlTransaction
  • 删除所有行目标表。
  • 从源到目标的批量复制(不要忘记通过交易)
  • 提交

这样一来,你会原子更新目标表。

我不确定你要做什么,但如果这是某种形式的缓存,请考虑彻底废除目标SQL服务器,并将数据作为对象数组存储在内存中。内存中对只读数据的访问速度非常快,并且您的数据集很容易适应内存。