可能的布局是每个维度都有一个 SCD2 表。
这是 DEPARTMENT 的示例

请注意,我添加了一个数字VERSION属性来唯一地定义版本的顺序。VALIDFROM_DATE列对应于用于构建维度的快照的有效性。通常还会添加 VALIDTO 日期以优化访问 - 为开放(最后)版本提供一些虚拟高值。
还要注意validfrom_date和start_date之间的设计区。前者是你获取信息的时间戳(从快照中),后者是逻辑有效性。在 2013 年 8 月 20 日的示例中,将在 2013 年 9 月 1 日创建一个新部门的信息。第二个版本代表一个部门的重命名,第三个版本表示该部门于 2015 年 9 月 1 日关闭。
这种维度通常由 ETL 作业定期处理快照、识别更改并构建维度来维护。
从事实表(即事务引用部门的表)中,维度通过 DEPARTMENTKEY 和可选的有效日期(以匹配正确的版本)来引用。
您还可以设置维度的当前视图(使用 PK DEPARTMENTKEY)。这是微不足道的,可以使用视图或物化视图和查询来完成,如下所示:
with dept as (
select
DEPARTMENTKEY,
min(VALIDFROM_DATE) over (partition by DEPARTMENTKEY) created_date,
VALIDFROM_DATE last_change_date, DEPARTMENTID, NAME,
FIRST_VALUE(NAME) over (partition by DEPARTMENTKEY order by VERSION) as INITIAL_NAME,
SEPC, START_DATE, END_DATE, IS_ACTIVE,
row_number() over (partition by DEPARTMENTKEY order by VERSION desc) as rn
from Department_history)
select
DEPARTMENTKEY, CREATED_DATE, LAST_CHANGE_DATE, DEPARTMENTID, NAME, INITIAL_NAME, SEPC, START_DATE, END_DATE, IS_ACTIVE
from dept
where rn = 1
order by DepartmentKey
您可以从历史记录表的所有日期中获利 - 查看属性 CREATED_DATE 和 INITIAL_NAME(您可以以非常低的成本优雅地实现 SCD3(新列))。

更新有效期至日期
如上所述,出于实际原因,历史维度实现了 VALIDTO 日期。此列在 ETL 作业中维护,每日快照的一种可能解决方案是将其设置为
- 开放版本的虚拟拉格雷日
- 下一个版本的 VALIDTO 日前一天
请注意,还有其他选项,但此模式的最大优点是您始终可以使用此谓词查询正确的版本
where to_date('01012015','ddmmyyyy') between validfrom_date and validto_date
我使用以下查询在此处添加 VALIDTO 日期
create table department_history2 as
with dept as (
select
DEPARTMENTKEY, VERSION, VALIDFROM_DATE,
lead(VALIDFROM_DATE-1,1,to_date('31122500','ddmmyyyy')) over (partition by DEPARTMENTKEY order by VERSION) as VALIDTO_DATE,
DEPARTMENTID, NAME, SEPC, START_DATE, END_DATE, IS_ACTIVE
from Department_history
)
select * from dept
更新查询每日计数
要从历史维度重建每日计数,您必须首先创建时间维度的相关部分(每天一条记录),然后将其加入历史维度。最后执行聚合。
这是从 2015 年 8 月 30 日开始“解压”4 天的示例
with snapshots as (
select to_date('30082015','ddmmyyyy') -1 + rownum transaction_date from dual connect by level <= 4),
deps_snaps as (
select
transaction_date, DEPARTMENTKEY, VERSION, VALIDFROM_DATE, VALIDTO_DATE, DEPARTMENTID, NAME, SEPC, START_DATE, END_DATE, IS_ACTIVE
from department_history2, snapshots
where transaction_date between validfrom_date and validto_date
)
-- aggregate
select transaction_date, count(*) active_dept_count
from deps_snaps
where is_active = 'Y'
group by transaction_date
order by transaction_date;
transaction_date active_dept_count
30.08.2015 00:00:00 2
31.08.2015 00:00:00 2
01.09.2015 00:00:00 1
02.09.2015 00:00:00 1
这种方法的最大优点是,如果一个部门改变,比如 3 年一次(大公司的典型间隔),该维度将不会有 5 * 365 倍的记录,但在 5 年内只有大约两倍。