【问题标题】:Incremental load across two different servers with different source DB’s具有不同源数据库的两台不同服务器的增量负载
【发布时间】:2018-06-05 08:54:38
【问题描述】:

我需要将我们的数据加载从完全加载更改为增量加载,并且通过此更改,我们将重建整个 ETL 流程。

以下是数据源基础架构现在的样子:

我们有两个生产服务器(用于两种不同的产品),比如说 P1P2。在 P1 上,我们的数据源是两个数据库:DB1DB2 位于链接服务器 S1 上。在 P2 上,链接服务器 S1 上只有一个数据库 DB3。将来将添加另一个数据库 DB4 for P2 和产品 P3。服务器 S1 上有显示所有数据的 SQL 视图。

还有我们的 ETL:

P1 和 P2 的两个不同 SSIS 项目,实际上仅在连接字符串上有所不同。 DB1 和 DB2 由 Union ALL SSIS 组件直接在数据流任务中合并。目前,SSIS 包正在执行存储在任务中的 SQL 查询,P1 的 ETL 更改会导致 P2 的 ETL 重做相同的更改。 数据在 P1 上每天加载两次,在 P2 上每 5 分钟加载一次,在数据加载过程中,所有内容都被截断并加载到两个数据仓库中的暂存表中。

目标:

我们的目标是创建一个具有参数化的通用 ETL 流程,允许我们在服务器 P2 上执行 SQL 时使用 DB3,在服务器 P1 上执行 SQL 时使用 DB1+DB2,并有可能将其扩展到 P3+DB4 和 DB3。我们还希望将 SQL 代码从包中移到存储过程中,这样从开发人员的角度来看,维护起来会更容易。
我们还需要让 ETL 在 P1 上更频繁地发生,但同时我们不允许在链接服务器上在短时间内多次查询整个数据集,一旦数据集随时间变大,这将在 P2 上出现问题。

我们要避免的事情: 动态 SQL。

在 SSIS 中创建增量数据加载和此类参数化的最佳做法是什么?我们一直与负责服务器 S1 的开发人员保持联系,如果我们需要任何类型的视图,他将能够提供。

【问题讨论】:

  • 使用临时表,加载所有数据,然后使用 SQL 来做增量工作。如果您有一个包含许多行的表,则在您的 SSIS 中使用参数化 SELECT,这样您就不必每次都加载完整的表。在最后一种情况下,您必须知道如何检索新的、最新的行,这取决于存储的数据(创建或修改日期、身份等)。操作结束后,注册执行的确切日期时间,以便您可以在下一次运行时从该点开始(我通常会减去几个小时来确定)。这种方法需要你所有的表都有键!
  • 您有一个带有数据流任务的包 PK1,目前它有两个 OLE DB 源 DB1 和 DB2。它将数据集合并在一起,然后转到.. S7,DB7 您还打包了看起来像 PK1 的 PK2,而不是数据集的合并,是吗?
  • 假设以上是正确的,希望有一个包从 N 个数据源中提取数据(因为数据模型在这些数据库实例之间是一致)并推入我们的目的地
  • 将 Package1 重新加工成两个数据流是否可以接受 - 一个从 DB1 中提取数据,然后返回并从 DB2 中提取数据。净效应是将相同(ish)数据带到目标,但从 SSIS 的角度极大地简化了问题
  • @billinkc 你是对的,但这有可能在 SSIS 中实现吗?我的意思是“一个从 DB1 中提取数据,然后返回并从 DB2 中提取数据”的部分。它应该取决于执行的服务器。

标签: sql-server ssis sql-server-2016 linked-server


【解决方案1】:

我会采用的一般模式是这样的。

我的控制流将识别与我们的项目关联的服务器上的数据库(连接管理器 = 源)

这里我展示了一个针对 sys.databases 的查询,因为也许您可以应用 AND D.Name IN ('DB1', 'DB2', 'DB3'); 之类的条件

在 S1 上,该查询将返回 2 个值,在 S2 上,仅返回 1 个。

我们将使用该数据库列表作为 ForEach 循环枚举器的源来“分解”结果。对于我们在原始查询中确定的每个值(DB1、DB2),我们将更新 Source ConnectionManager 的InitialCatalog 属性。在下面的参考答案中,我设置了 ConnectionString 属性,但您只想修改 InitialCatalog。所以每次循环,指向的数据库都会改变。

然后将 ForEach 枚举器中的数据流简化为仅处理当前数据库,而不必担心此服务器有 3 个还是 1 个源数据库。

注意事项

源查询和数据类型必须在所有相关数据库中兼容。数据流的结构是在设计时设置的,在运行时不能更改。

如果实体在数据库中是一致的,只是列被称为不同的东西,请在每个数据库中创建一个视图以确保实体名称是一致的,然后您可以避免使用动态 SQL。

您需要在包开始时提供 Source 连接字符串的初始值。这可以通过调用时的 SET 属性来完成。

参考答案

探索这些概念的一些相关 SSIS 答案

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-24
    相关资源
    最近更新 更多