2011-10-10 59 views
2

比方说,我想将所有客户(或某些其他特定表中的所有行)导入到某个外部系统。并非全部一次,而是在数据库中创建后的每一个。为此,我必须记录所有已经报告的行,因为我只想找到尚未报告的行。添加一列来做这件事或创建某种批处理日志表通常会更好吗?如何跟踪哪些行已经在SQL中导入?

我使用MS SQL服务器,如果是相关

一个简单的例子:

SELECT * FROM客户那里reportedToExternalSystem为空

SELECT * FROM客户那里cus_id不在(从集成批处理日志中选择cus_id)

或者是否有更多的方法可以做到这一点你会更好吗?这是我第一次做这样的事情,所以我还不知道最佳做法。

回答

1

简单的解决方案是添加一个将行标记为导入的列。状态int(0/1),或者如果要跟踪导入日期的时间。此解决方案确实有一些限制:

  1. 您只能导入一行。记录更新时是否需要再次导入客户?客户更新时是否要清除更新字段?

  2. 当您更新行状态时,会导致行被锁定。您确定插入客户记录的应用程序会对您的代码锁定记录感到满意吗?

  3. 在某些系统上,它会将整行写入日志系统进行恢复。根据行的大小,这可能只是一个字段的大量日志写入。

  4. 在高度并行的导入系统中,您可能会产生大量资源争用。如果一个导入程序正在锁定该表,请考虑如果许多导入程序同时锁定该表会有多糟糕。

  5. 如果客户数据在您的导入轮询时间间隔内多次更新,您将只能看到最新数据并跳过中间更新。这只是一个问题,如果你关心intermedaite更新。对于你可能不在乎的顾客,对于订单状态你可能会关心很多。

  6. 您必须修改表结构。由于数据/支持/政治问题,源应用程序可能不允许这样做。

除了在表中添加状态列,一种很好的方法是在表上放置触发器并将导入数据镜像到第二个表中。然后你会'消耗'第二个表中的数据。这有几个优点:

  1. 它保持包含到第二个表的锁定问题。

  2. 它允许您处理主表的每个更新。

  3. 您可以向第二个表添加索引,该索引用于跟踪更新状态,而不会更改主表。

  4. 如果您从第二个表中删除行(或者在它们被消耗后或在短的审计周期后立即删除),那么表/索引的大小将会最小。

当我在Sql Server中使用这种技术时,我把第二个表放在一个单独的模式中。由于大多数应用程序都以dbo存储他们的表格,因此最终可能会出现dbo.Customers和Import.Customers。这可以帮助您跟踪要导入的表格,并防止您为导入表格提供新名称。

+0

伟大的总结,确实+1 –

0

我会使用一个单独的表格,例如说,导入日期与您正在跟踪的表格中的记录关键字相互参照。换句话说,一个包含3列的表:自动递增键,来自其他表的记录标识,导入日期。类似的东西。如果记录稍后再被重新输入,这也允许这种情况。你会按日期跟踪所有的进口。

+0

在这种情况下,这会导致数据冗余。即使在源表中维护列也可以用于重新导入状态。只需将其声明为默认情况下初始值为'0'的数字列类型,并在每次导入时将其添加为'1'。你说啥? –

+0

我指出的解决方案提供了“最大的功能”,因为原始的海报不清楚是否只需要每个键的一个输入日期,我把它作为选项扔在“凯迪拉克”解决方案中。当然有几个很好的解决方案,但是OP将需要根据他们的具体要求来选择。 – lurker

0

我希望有一个column for importing status。维护一个单独的日志导致时间消耗的结果随着桌子大小的增加。我确实在SQL Server上有概念上的想法,但看起来很有效。继续发帖!

1

除非你有复杂的实施,尽可能与最简单的解决方案。你应该考虑的一件重要事情是,如果你需要它,重构这个简单到更一般的程序是多么困难。

在你的情况,我看到只有一个问题,从列升级到表。如果你需要进口的历史。解决方案:使reportedToExternalSystem列的DateTime(或时间戳)类型