2

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

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

我考虑过保存最新的 ID 并只获取更新的所有内容,但旧数据有可能(不太可能但仍然可能)被更改。就这样我会错过改变的数据。

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

4

1 回答 1

3

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

听上去,你的整张桌子可以轻松容纳在 100MB 中。这只是没有多少数据。假设您可以获得 10MB/s 的传输速率(这一点也不奇怪),您可以在 10 秒内传输所有内容。如您所说,如果您只需要几列,则总数据传输可能会少得多。每五分钟使用 10 秒的数字,这将是大约 3% 的负载以保持数据最新 - 这是对源数据库的微不足道的查询,可能不会导致太多负载,尤其是因为它'由于数据集非常小,因此将全部缓存在内存中。

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

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

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

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

这样,您将自动更新目标表。

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

于 2013-01-31T12:23:05.313 回答