如何创建临时表来处理增量负载

Posted

技术标签:

【中文标题】如何创建临时表来处理增量负载【英文标题】:How to create staging table to handle incremental load 【发布时间】:2014-01-02 12:13:45 【问题描述】:

我们正在设计一个Staging layer 来处理incremental load。我想从一个简单的场景开始设计staging

在源数据库中有两个表ex,tbl_Department,tbl_Employee。这两个表都在目标数据库 ex tbl_EmployeRecord 中加载单个表。

正在加载 tbl_EmployeRecord 的查询是,

SELECT EMPID,EMPNAME,DEPTNAME 
FROM tbl_Department D 
INNER JOIN tbl_Employee E 
ON D.DEPARTMENTID=E.DEPARTMENTID

现在,我们需要识别 tbl_Department、tbl_Employee 中的增量负载并将其存储在 staging 中,并且仅将增量负载加载到目的地。

表格的列是,

tbl_Department : DEPARTMENTID,DEPTNAME tbl_Employee : EMPID,EMPNAME,DEPARTMENTID tbl_EmployeRecord:EMPID、EMPNAME、DEPTNAME

请建议如何为此设计暂存以处理插入、更新和删除。

【问题讨论】:

【参考方案1】:

识别增量数据

增量加载需要基于源表中存在的一些隔离信息。此类信息可帮助您识别将加载的数据的增量部分。通常,记录的加载日期或上次更新日期是一个不错的选择。

考虑到这一点,您的源表有一个日期列,该列存储记录的插入日期以及对该记录进行任何更新的日期。在分段加载期间的任何一天,您都可以利用此日期来确定哪些是自上次分段加载以来新插入或更新的记录,并且您仅将那些更改/更新的记录视为您的增量增量。

鉴于您的表格结构,我不确定您可以使用哪一列。 ID 列将无济于事,就好像记录已更新您不会知道一样。

维护加载历史记录

重要的是存储有关您今天加载了多少的信息,以便您可以在下一次加载时加载下一部分。为此,请维护一个临时表 - 通常称为 Batch Load Details 表。该负载通常具有如下结构:

BATCH ID | START DATE | END DATE  | LOAD DATE | STATUS
------------------------------------------------------
1        | 01-Jan-14  | 02-Jan-14 | 02-Jan-14 | Success

在开始数据加载之前,您需要每天在此表中插入一条新记录。新记录的开始日期将等于上次成功加载的结束日期并且状态为空。加载成功后,您将更新状态为“成功”

修改数据提取查询以利用批量加载表

一旦您像上面一样维护了加载历史记录,您就可以在提取查询中包含此表,

SELECT EMPID,EMPNAME,DEPTNAME 
FROM tbl_Department D 
INNER JOIN tbl_Employee E 
ON D.DEPARTMENTID=E.DEPARTMENTID
WHERE E.load_date >= (SELECT max(START_DATE) FROM BATCH_LOAD WHERE status IS NULL)

我要建议你的绝不是一个标准。事实上,您应该根据您的要求仔细评估我的建议。

建议

对事务数据使用增量加载,而不是主数据。交易数据的容量通常较高,并且可以很容易地以增量块的形式分离。主数据往往更易于管理,并且每次都可以完全加载。在上面的示例中,我假设您的 Employee 表的行为类似于事务数据,而您的部门表是您的主表。

我相信this article on incremental loading会对你很有帮助

【讨论】:

文章链接失效【参考方案2】:

我不确定您使用的是什么数据库,所以我只从概念上讲。如果您想为特定技术添加标签,我们可能会提供具体建议。

看起来每个员工都有 1 行,并且您只保留每个员工的当前记录。我将假设 EMPID 是独一无二的。

首先,向当前填充维度的查询添加一个字段。该字段将是表 EMPID、EMPNAME、DEPTNAME 中其他字段的哈希。您可以创建视图、填充新的临时表或仅使用查询。还将这个相同的哈希字段添加到维度表中。基本上,散列是一种简单的方法来生成一个字段,该字段对于每条记录都是唯一的并且可以有效地进行比较。

插入:这些是 EMPID 尚未存在于维度表中但存在于您的暂存查询/视图中的记录。

更新:这些是 EMPID 在暂存查询/查看维度表中的记录,但哈希字段不匹配。

删除:这些是 EMPID 存在于维度中但不存在于暂存查询/视图中的记录。

如果这将是大容量,您可能需要创建新表来保存应该插入的记录和应该更新的记录。识别记录后,您可以一次插入/更新它们,而不是一个一个地插入/更新它们。

从数据仓库中删除大量记录并不常见,因为它们通常用于保存历史记录。我建议也许创建一个作为状态或位字段的列,以指示源中是否处于活动状态或已删除。当然,您如何处理删除应该取决于您的业务需求/报告要求。请记住,如果您进行硬删除,如果您决定以后需要它,您将永远无法取回该数据。

就地更新现有维度(而不是为每次更改创建历史记录)在维度建模术语中称为类型 1 维度。这是相当普遍的。但是,如果您决定需要保留历史记录,则可以使用散列来帮助您创建 SCD 类型 2 记录。

【讨论】:

@Jim 您可能希望将您的观点编辑到问题中,而不是发布您的 cmets 作为答案。

以上是关于如何创建临时表来处理增量负载的主要内容,如果未能解决你的问题,请参考以下文章

仓库更新的增量负载

MySQL 仅从 SELECT 创建具有自动增量的临时表

mysql数据库怎么把查询出来的数据生成临时表

临时表的问题

如何在没有临时表的 SQL 查询中为组添加序列号

Oracle 存储过程 - 创建游标后我可以清空临时表吗