跨具有不同源数据库的两个不同服务器的增量负载

Incremental load across two different servers with different source DB’s

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

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

我们有两个生产服务器(用于两个不同的产品),比方说 P1P2。在 P1 我们的数据源是两个数据库:DB1DB2 位于链接服务器 S1。在 P2 上,链接服务器 S1 上只有一个数据库 DB3。将来会为 P2 和产品 P3 添加另一个数据库 DB4。服务器 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 上执行时允许我们使用 DB1+DB2,并有可能将其扩展到P3+DB4 和 DB3。我们还想将 SQL 代码从包中移动到存储过程中,这样从开发人员的角度来看维护起来会更容易。
我们还需要让 ETL 在 P1 上更频繁地发生,但同时我们不允许在短时间内在链接服务器上多次查询整个数据集,一旦数据集随时间增长,这将成为 P2 上的问题。

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

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

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

我的控制流将识别与我们的项目关联的服务器上的数据库(Connection Manager = Source)

这里我显示了针对 sys.databases 的查询,因为也许您可以应用像 AND D.Name IN ('DB1', 'DB2', 'DB3');

这样的条件

在 S1 上,该查询将 return 2 个值,在 S2 上,只有 1 个。

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

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

注意事项

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

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

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

参考答案

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

  • 连接管理器上的表达式
  • 粉碎记录集
  • DTEXEC 和 SET
  • SET 仍然相关