1

我手头的任务是为数据库创建某种逻辑。今天有一个 IBM MQ 系列设置,可以从几个远程系统复制数据。目前它在远程系统中发生变化并将数据转储到 SQL Server 2005 数据库中的临时表中。

我想根据一些简单的验证逻辑(必填字段和数据格式)和数据层次结构的一些更高级的检查来验证数据。正在导入的数据是分层的,其中一些数据之间存在父子关系。分层验证应检查暂存表和生产表中当前可用的数据,以确保在导入完成后存在有效的层次结构。

如果记录验证失败,应该以某种方式记录失败并且不应该导入失败的记录,但应该导入剩余的记录。如果当前生产表中的记录具有相同的 id,则应将其替换为新记录。在数据出现在临时表中之后,应尽快从临时表传输数据。

据我所知,生产表中的记录总数不会超过100万条,每批更新项目的可能数量最多为几千行。

我的问题是什么解决方案最适合导入数据?

我想到了几个可能的解决方案:

开始转移的方式:

  • 定期轮询临时表并在插入新数据时启动某种传输过程的 Windows 服务。
  • 将新数据插入表中时,使 MQ 启动传输过程
  • 安排 SSIS 作业定期运行

验证和传输数据的方法:

  • 创建 SSIS 作业
  • 创建存储过程
  • 自定义 .NET 代码

我主要担心的是,生产表中的层次结构必须始终保持不变,并且数据应该在出现在暂存表中后不久就可以在生产表中使用。我不能确定临时表中是否始终有完整的层次结构可用。

4

1 回答 1

0

我们对此类工作使用封闭流程。

从远程系统获取数据到暂存表中,导入到产品表中。

如果任何东西都可以随意插入到临时表中,并且有子表,那么您可能会在临时表中创建所有子记录之前导入到生产数据库中。

如果您可以自由地将列添加到暂存表(远程端将忽略),或者如果暂存表具有唯一/非重复的 IDENTITY 或 GUID,那么您可以创建一个并行表。

理想情况下,在暂存表中创建行的例程将使用批次编号,然后在成功时创建“批次编号完成”记录。所以你有一个信号量来阻止你导入,直到所有关联的记录都进来。

(它们可以插入到事务块中,但您必须确信插入到暂存表中的所有进程都遵守了这一点)。

给定 IDENTITY / GUID,我将创建一个 1:1 的“错误表”来存储任何描述导入失败的消息。

您可以选择将失败的行移动或复制到单独的故障暂存表中,这样主暂存表就不会被阻塞,并且更容易确保故障被整理出来(我认为是由人)。

说了这么多,这里对我们的具体流程做一个更详细的描述:

为了最小化带宽和更新(即减少阻塞和最小化不必要的事务日志条目等),我们执行以下操作:

在源机器上保存正在传输的表的副本。这有用于更新和操作的附加列(更新或删除标志 - 更新包括插入,并且插入可能在目标获得该行之前再次更新......)

插入到这个表中,的行都可以

仅当至少一列存在差异时才会更新此表 - 因此可以(如果相当 CPU 密集型)将整个源表与暂存表进行比较以找出发生了什么变化。更新设置已更新列。(注意时钟何时返回)

如果在源表中找不到它们,我们会定期标记 stagin 表行 Action=Deleted。

数据从 Source 复制到 Destination 上的相同表,其中 Updated-on 是在最后一次传输之后。

在目标服务器上,检查数据并将其导入生产的例程仅在更新日期工作(处理自上次更新日期以来的所有内容)

所有临时表都在一个单独的数据库中,该数据库具有最少的日志记录——如果数据库恢复,数据库将自动从“上次更新日期”刷新,因此我们的目标是最小化事务日志。我们不会将临时表存储在生产数据库中(它将具有完整的事务日志记录),以避免 TLogs 膨胀

同样,如果这些过程是连续的,这样它们就不会同时发生,这将很有帮助,否则需要某种批次编号来防止传输存在父/子表的部分完成的批次。

我们以 Source 数据库的方式传输数据,只在 Destination 端进行数据操作。这样做的原因是,如果数据操作错误,并且我们修复了它,我们只需要在目标端重新运行它 - 源数据都存在于目标端的临时表中。如果我们在源端进行操作,我们也必须再次重新传输所有数据。

对于调试,在暂存表中具有更新日期是有帮助的。我们经常得到“为什么这不同”并且看到更新后告诉我们目标端的操作是否有问题(即我们有显示预期源数据的最近数据)或源端(没有找到最近的数据! )

于 2009-02-16T11:09:21.213 回答