我在确定哪个方案对我的方案更好时遇到了麻烦。这个场景中涉及的维度是
员工维度
╔═════════════╦════════════╦════════╦════════╦═══════════╦══════════╦════════╗
║ 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 ║
╚═════════════╩════════════╩════════╩════════╩═══════════╩══════════╩════════╝
部门维度
╔═══════════════╦══════════════╦══════╦══════╦═══════════╦═════════╦════════╗
║ 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 ║
╚═══════════════╩══════════════╩══════╩══════╩═══════════╩═════════╩════════╝
员工情况表(每日)
我的问题
实现每日快照事实表的正确和最充分的方法是什么,因为他们知道Department Dimension包含有效的700万条记录,而Departments Dimension包含有效的500,000条记录。
是否足以每天填充事实员工和事实部门并每天重复记录?
我正在使用SQL Server 2014数据库并期望使用OLAP
答案 0 :(得分:0)
为什么你想每天快照你的事实?事实应该包含所有数据。事实上的日期键应该足以处理基于日期的查询。
此外,我不建议将员工和维度作为事实 - 他们看起来很直接。事实应该是衡量我在这里看不到的东西。围绕在某个部门工作的员工完成的某些流程/交易来构建您的事实。将此事实与两个维度和日期维度相关联。如果要保留事务中更改的历史记录,请启用维度SCD。
答案 1 :(得分:0)
可能的布局是为每个维度设置一个SCD2表。
请注意,我添加了一个数字 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(新列))。
将VALID更新为日期
如上所述,由于实际原因,历史维度offen实现了VALIDTO日期。此列在ETL作业中维护,每日快照的一种可能解决方案是将其设置为
请注意,还有其他选项,但此架构的一大优势是您始终可以使用此谓词查询正确的版本
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>