数据仓库和类型2 SCD和/或每日快照事实表

时间:2015-09-30 21:02:41

标签: ssas data-warehouse business-intelligence datamart

我在确定哪个方案对我的方案更好时遇到了麻烦。这个场景中涉及的维度是

  1. 员工维度

    ╔═════════════╦════════════╦════════╦════════╦═══════════╦══════════╦════════╗
    ║ EmployeeKey ║ EmployeeID ║ DeptID ║ Salary ║ StartDate ║ EndDate  ║ Active ║
    ╠═════════════╬════════════╬════════╬════════╬═══════════╬══════════╬════════╣
    ║ 1           ║ 1          ║ 1      ║ 9000   ║ 20150901  ║ 20150930 ║ FALSE  ║
    ║ 2           ║ 2          ║ 3      ║ 5000   ║ 20150901  ║ NULL     ║ TRUE   ║
    ║ 3           ║ 1          ║ 1      ║ 9500   ║ 20150930  ║ NULL     ║ TRUE   ║
    ╚═════════════╩════════════╩════════╩════════╩═══════════╩══════════╩════════╝
    
  2. 部门维度

    ╔═══════════════╦══════════════╦══════╦══════╦═══════════╦═════════╦════════╗
    ║ DepartmentKey ║ DepartmentID ║ Name ║ Sepc ║ StartDate ║ EndDate ║ Active ║
    ╠═══════════════╬══════════════╬══════╬══════╬═══════════╬═════════╬════════╣
    ║ 1             ║ 1            ║ XXXX ║ AWK  ║ 20150901  ║ NULL    ║ TRUE   ║
    ║ 2             ║ 2            ║ YYYY ║ AUTO ║ 20150901  ║ NULL    ║ TRUE   ║
    ║ 3             ║ 3            ║ ZZZZ ║ AMD  ║ 20150901  ║ NULL    ║ TRUE   ║
    ╚═══════════════╩══════════════╩══════╩══════╩═══════════╩═════════╩════════╝
    
  3. 员工情况表(每日)

  4. 部门事实表(每日)
  5. 我的问题

    1. 实现每日快照事实表的正确和最充分的方法是什么,因为他们知道Department Dimension包含有效的700万条记录,而Departments Dimension包含有效的500,000条记录。

    2. 是否足以每天填充事实员工和事实部门并每天重复记录?

    3. 我正在使用SQL Server 2014数据库并期望使用OLAP

2 个答案:

答案 0 :(得分:0)

为什么你想每天快照你的事实?事实应该包含所有数据。事实上的日期键应该足以处理基于日期的查询。

此外,我不建议将员工和维度作为事实 - 他们看起来很直接。事实应该是衡量我在这里看不到的东西。围绕在某个部门工作的员工完成的某些流程/交易来构建您的事实。将此事实与两个维度和日期维度相关联。如果要保留事务中更改的历史记录,请启用维度SCD。

答案 1 :(得分:0)

可能的布局是为每个维度设置一个SCD2表。

以下是DEPARTMENT的示例 enter image description here

请注意,我添加了一个数字 VERSION 属性来唯一定义版本的顺序。 列 VALIDFROM_DATE 对应于用于构建维度的快照的有效性。 通常还会添加VALIDTO日期以优化访问 - 对于开放(最后)版本,使用一些虚拟高值。

另请注意,validfrom_date和start_date之间的设计区域。 前者是获取信息的时间戳(来自快照),后者是逻辑有效性。 在示例中,您在2013年8月20日获得了将在01.09.2013创建新部门的信息。 第二个版本代表一个部门的重命名,第三个版本表示在1.9.2015这个部门关闭了。

这样的维度通常通过ETL作业定期处理快照来维护,识别更改并构建维度。

从事实表(即具有引用Department的事务的表)中,使用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(新列))。

enter image description here

将VALID更新为日期

如上所述,由于实际原因,历史维度offen实现了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

这种方法的一大优势在于,如果一个部门在三年内改变一次(大公司的典型间隔),那么这个维度将不会有5 * 365倍的记录,但在5年内只会大约两倍。 / p>