2

作为一名建模者,试图找出在 SCD 类型 2 表中处理删除的最佳方法是什么。

根据原则,SCD 类型 2 表使用 START_DT 和 END_DT 等 ETL 日期来跟踪更改。

  1. START_DT 将是记录生效的日期。
  2. END_DT 将是它更改为另一种形式的日期或 Null/High Date 以表示当前版本的记录。
  3. 在所有时间点,对于键组合,都会有一个当前版本记录,其 END_DT 为空日期或高日期。

现在,如果从源中删除记录,下面的最佳选择是什么,

  1. 如果从源中删除记录,则有额外的列,如 SRC_DELETE_IND,默认设置为“N”和“Y”。
Ex: Record came on 1st Oct
PK_ID START_DT    END_DT     VALUE SRC_DELETE_IND
1     2021-10-01  Null       ABC    N
Record had an update on 2nd Oct
PK_ID START_DT    END_DT     VALUE SRC_DELETE_IND
1     2021-10-01  2021-10-02  ABC    N
1     2021-10-02  Null        XYZ    N
Record got deleted on 3rd Oct
PK_ID START_DT    END_DT     VALUE SRC_DELETE_IND
1     2021-10-01  2021-10-02  ABC    N
1     2021-10-02  Null        XYZ    Y
  1. 与 1 相同,但在 Delete Came 时插入新的重复行。
Record got deleted on 3rd Oct
PK_ID START_DT    END_DT     VALUE SRC_DELETE_IND
1     2021-10-01  2021-10-02  ABC    N
1     2021-10-02  2021-10-03  XYZ    N
1     2021-10-03  Null        XYZ    Y
  1. 而不是 SRC_DELETE_IND 记录的过期/结束日期
Record got deleted on 3rd Oct
PK_ID START_DT    END_DT     VALUE 
1     2021-10-01  2021-10-02  ABC   
1     2021-10-02  2021-10-03  XYZ   

但是这里我们现在没有打开记录了。

如果记录重新出现在 Source 中并声明为不正确删除,则会增加复杂性。让我们在 10 日说,对于选项 1,数据看起来像,

PK_ID START_DT    END_DT     VALUE SRC_DELETE_IND
1     2021-10-01  2021-10-02  ABC    N
1     2021-10-02  Null        XYZ    N --Reversed

对于选项 2

PK_ID START_DT    END_DT     VALUE SRC_DELETE_IND
1     2021-10-01  2021-10-02  ABC    N
1     2021-10-02  2021-10-03  XYZ    N
1     2021-10-03  Null        XYZ    N  -- Reversed but now row is duplicate

对于选项 3

PK_ID START_DT    END_DT     VALUE 
1     2021-10-01  2021-10-02  ABC   
1     2021-10-02  2021-10-03  XYZ   
1     2021-10-10  Null        XYZ  --considered as New since no open record existed. Creates ETL gap

哪个选项更有意义,并且符合 DWH 最佳实践。

4

1 回答 1

1

我会采用一种更简单的方法,为已删除的记录设置一个默认的 END_DATE ,例如 1000-12-31 :

PK_ID START_DT    END_DT     VALUE 
1     2021-10-01  2021-10-02  ABC   
1     2021-10-02  1000-12-31  XYZ --> this row is deleted

此外,避免使用 NULL 值。NULL 值表示缺少值,这与零值不同。SQL NULL 是一个状态,而不是一个值。这种用法与大多数编程语言完全不同,其中引用的 null 值意味着它没有指向任何对象。

我建议您为 END_DT 使用默认日期,例如 9999-12-31,因此在插入行时,您的维度将如下所示:

 PK_ID START_DT    END_DT     VALUE 
 1     2021-10-01  9999-12-31  ABC 

代替 :

PK_ID START_DT    END_DT     VALUE 
1     2021-10-01  NULL       ABC 

我建议您在维度中添加代理键。维度表设计有一个列作为唯一的主键。此主键不能是操作系统的自然键,因为随着时间的推移跟踪更改时,该自然键将有多个维度行。此外,一个维度的自然键可能由多个源系统创建,这些自然键可能不兼容或管理不善。DW/BI系统需要声称控制所有维度的主键;您应该为每个维度创建匿名整数主键,而不是使用显式自然键或带有附加日期的自然键。这些维度代理键是简单的整数,按顺序分配,从值 1 开始,每次需要新键时。日期维度不受代理键规则的约束;这个高度可预测和稳定的维度可以使用更有意义的主键。

于 2021-10-14T12:01:49.520 回答