【问题标题】:How to write a basic ETL using SQL without truncate/load at each ETL run?如何在每次 ETL 运行时使用 SQL 编写基本 ETL 而无需截断/加载?
【发布时间】:2022-01-01 03:18:02
【问题描述】:

我有一个 OLTP 数据库,我正在使用 SQL (ETL) 将其加载到另一个数据库中。为此,在第二个数据库中,我创建了基于事实和维度的星型模式模型。

技术:MS-SQL

事实:销售

维度:客户、客户、代理

注意:源系统中没有修改日期字段,源系统中可以删除行。

我有一个每 15 分钟运行一次的代理作业来执行以下操作:对于每个表,我将 OLTP db 中的数据加载到各自的暂存表中(对于每个维度和事实表)。然后将暂存的暗表合并到暗表中。然后更新暂存事实表以包含维度的代理键。然后使用合并将暂存事实表与事实表同步。这是资源消耗,因为我必须在每次 etl 运行时将整个数据加载到临时表中。所以我正在寻找一种更好的方法 - 如果有人可以指出它是如何完成的,它将对我有所帮助。

【问题讨论】:

  • 您没有记录的状态更改数据。您没有确定可以保证不重用的密钥。因此您无法跟踪可能/可能不具有相同值的删除/插入。您可以将触发器添加到表和时间戳字段以跟踪更新,并有一个删除表被触发器添加到删除。然后使用这个新的列和表来跟踪状态变化;但这需要更改源系统。
  • 你说You have no key identified which has a guaranteed non-reuse. 。源系统表具有自动递增的主键,因此可以保证不可重用。
  • 好的。因此,当发生更改/创建时,我将返回触发更新列时间戳。提取自上次运行时间戳以来的所有更改。删除触发器。那么你的 ETL 是两个步骤:1)使用时间戳 >= 最后一次运行和合并拉取任何东西。 2)使用时间戳> =上次运行拉取所有删除并从目标中删除。必须在 ETL 中记录上次运行日期/时间并在完成时更新。因为有身份;我们不必担心身份重用的边缘情况
  • 很遗憾,我无法更改源数据库。因此无法编写触发器或更改表架构。那么我目前的方法是最好的吗?
  • 您无法识别更改状态;所以你基本上每次都删除所有数据并提取所有数据。我个人认为没有其他方法,除非您可以 merge replicate 数据库到您可以控制的东西;或者尽管log shipping 并建立更改状态信息,然后将您的 ETL 建立在副本/辅助数据库的基础上......

标签: sql-server tsql ssis etl data-warehouse


【解决方案1】:

这是资源消耗,因为我必须在每次 etl 运行时将整个数据加载到临时表中

  1. 在源中开启Change TrackingChange Data Capture,只提取更改的行

  1. 在 DW 服务器上使用 Transactional Replication 从源到暂存表或使用 Read-Scale ReplicaLog Shipping 创建可读副本。

【讨论】:

  • 我是否正确理解第二点仅在每次 ETL 运行期间阻止网络传输并且我仍需要进行截断和加载?
  • 您可以从副本合并到数据集市。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-09
  • 2012-11-29
  • 1970-01-01
  • 1970-01-01
  • 2019-10-26
  • 1970-01-01
相关资源
最近更新 更多