跨具有不同源数据库的两个不同服务器的增量负载
Incremental load across two different servers with different source DB’s
我需要将我们的数据加载从完全加载更改为增量加载,并且通过此更改,我们将重建整个 ETL 过程。
这是数据源基础架构现在的样子:
我们有两个生产服务器(用于两个不同的产品),比方说 P1 和 P2。在 P1 我们的数据源是两个数据库:DB1 和 DB2 位于链接服务器 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 仍然相关
我需要将我们的数据加载从完全加载更改为增量加载,并且通过此更改,我们将重建整个 ETL 过程。
这是数据源基础架构现在的样子:
我们有两个生产服务器(用于两个不同的产品),比方说 P1 和 P2。在 P1 我们的数据源是两个数据库:DB1 和 DB2 位于链接服务器 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 仍然相关