数据仓库
业务系统和数仓的区别
拉链表
概念
数据仓库保留了大量的历史数据,对时间维度上的数据分析工作提供了重要的手段。而保留历史数据的最常见的方法就是使用历史拉链表,历史拉链表仅当数据发送变更时,才相应的发生变更,这样就能有效保留历史数据的变动信息,又不会浪费存储空间。
适用于以下场景:
数据量有点大,表中某些字段有变化,但是变化的频率也不是很高,业务需求又需要统计这种变化状态,每天全量一份呢,有点不太现实,不仅浪费了存储空间,有时可能业务统计也有点麻烦,这时,拉链表的作用就体现出来了,既节省空间,又满足了需求。
一般通过在数仓中增加start_date和end_date字段来实现,其中start_date表示该条记录的生命周期开始时间,end_date表示该条记录的结束生命周期(不包括该日期)。
1 支付 2016-08-21 2016-08-21
1 完成 2016-08-22 9999-12-31
2 创建 2016-08-20 2016-08-20
2 完成 2016-08-21 9999-12-31
3 创建 2016-08-20 2016-08-21
3 支付 2016-08-22 9999-12-31
4 创建 2016-08-21 2016-08-21
4 支付 2016-08-22 9999-12-31
5 创建 2016-08-22 9999-12-31
比如上面就是一个数仓中订单表中(order_his
)的数据,其中最后两列是start_date和end_date字段,
end_date=‘ 9999-12-31’表示该条记录目前处于有效状态,而其他则表示是一段历史.
--如果查询当前所有有效的记录
select * from order_his where dw_end_date = ‘9999-12-31′
--如果查询2016-08-21的历史快照
select * from order_his where begin_date <= ‘2016-08-21′ and end_date >= ‘2016-08-21’
拉链算法
- 采集当日全量数据到ND(NewDay)表;
- 可从历史表中取出昨日全量数据存储到OD(OldDay)表;
- (ND-OD)就是当日新增和变化的数据,也就是当天的增量,用W_I表示;
- (OD-ND)为状态到此结束需要封链的数据,用W_U表示;
- 将W_I表的内容全部插入到历史表中,这些是新增记录,start_date为当天,而end_date为max值;
- 对历史表进行W_U部份的更新操作,start_date保持不变,而end_date改为当天,也就是关链操作;
更新操作
这里举个栗子说明,并且以天为维度做拉链.
首先我们创建表结构:
--订单流水表
CREATE TABLE orders (
orderid INT,
createtime STRING,
modifiedtime STRING,
status STRING
) row format delimited fields terminated by '\t'
--订单增量表
CREATE TABLE ods_orders_inc (
orderid INT,
createtime STRING,
modifiedtime STRING,
status STRING
) PARTITIONED BY (day STRING)
row format delimited fields terminated by '\t'
--订单数仓历史表
CREATE TABLE dw_orders_his (
orderid INT,
createtime STRING,
modifiedtime STRING,
status STRING,
dw_start_date STRING,
dw_end_date STRING
) row format delimited fields terminated by '\t' ;
第一次历史表中没有数据,需要全量更新(这里假设订单流水表中已经有数据了),
全量更新数据,我们先到2016-08-20为止的数据(假设第一天数据变化日期是2016-08-20):
--初始化,先把2016-08-20的数据初始化到增量表
INSERT overwrite TABLE ods_orders_inc PARTITION (day = '2016-08-20')
SELECT orderid,createtime,modifiedtime,status
FROM orders
WHERE createtime < '2016-08-21' and modifiedtime <'2016-08-21';
--再初始化到历史表
INSERT overwrite TABLE dw_orders_his
SELECT orderid,createtime,modifiedtime,status,
createtime AS dw_start_date,
'9999-12-31' AS dw_end_date
FROM ods_orders_inc
WHERE day = '2016-08-20';
通过上面可以知道:
- 增量表里存了一份全量数据
- 历史表中也存了一份全量数据,并且表示为当前有效
然后我们再接着更新2016-08-21的数据:
--1.保存一份2016-08-21的增量数据到增量表中
INSERT overwrite TABLE ods_orders_inc PARTITION (day = '2016-08-21')
SELECT orderid,createtime,modifiedtime,status
FROM orders
WHERE (createtime = '2016-08-21' and modifiedtime = '2016-08-21') OR modifiedtime = '2016-08-21';
--2.然后增量表关联到一张临时表中,再插入到新表中
--临时表
DROP TABLE IF EXISTS dw_orders_his_tmp;
CREATE TABLE dw_orders_his_tmp AS
SELECT orderid,
createtime,
modifiedtime,
status,
dw_start_date,
dw_end_date
FROM (
SELECT a.orderid,
a.createtime,
a.modifiedtime,
a.status,
a.dw_start_date,
CASE WHEN b.orderid IS NOT NULL AND a.dw_end_date > '2016-08-21' THEN '2016-08-21' ELSE a.dw_end_date END AS dw_end_date
FROM dw_orders_his a
left outer join (SELECT * FROM ods_orders_inc WHERE day = '2016-08-21') b
ON (a.orderid = b.orderid)
UNION ALL
SELECT orderid,
createtime,
modifiedtime,
status,
modifiedtime AS dw_start_date,
'9999-12-31' AS dw_end_date
FROM ods_orders_inc
WHERE day = '2016-08-21'
) x
ORDER BY orderid,dw_start_date;
--插入到历史表
INSERT overwrite TABLE dw_orders_his;
更新2016-08-22的数据和上面的步骤2类似.
通过上面可知,每天历史表拉链数据变更包括两部分(以2016-08-21举例):
- 2016-08-21当天的全部增量数据,其所有记录是有效的
- 已经存到历史表中的数据,如果2016-08-21当天有增量更新,则该条记录生命周期结束时间记录为2016-08-21这天
当然除了上面的,在库里存着的这次没有变更的原样保存,不做更改。
结论
- 拉链表中存的是一段时间的快照
- 这样减少了数据的冗余
- 如果start_date和end_date有索引的话,查询性能会大大提高
模型
3NF
主要目的是消除冗余。
E-R图.
维度建模
为什么说维度建模是展现分析数据的首选技术?
- 以商业用户可理解的方式发布数据
- 提供高效的查询性能
事实表和维度表
事实表
维度模型中的事实表存储组织机构业务过程事件的性能度量结果.
“事实”这一术语表示某个业务度量.
事实表中的每行对应一个度量事件.每行中的数据是一个特定级别的细节数据,称为粒度。例如,销售事务中用一行来表示每个卖出去的产品。维度建模的核心原则之一是同一事实表中的所有度量行必须具有相同的粒度。
一般事实表具有两个或者更多个外键与维度表的主键关联。
事实表通常有包含外键集合的主键。事实表的主键常称为组合键,具有组合键的表称为事实表。事实表表示多对多关系。其他表称为维度表。
通常几个维度一起唯一标识某个事实表行。当确定了所有维度中唯一标识事实表行的子集后,其他维度使用事实表行的主键的单一值。换句话说,其他维度只是参与其中。
维度表
每个维度表有单一的主键定义,用于在与事实表连接操作时实现参照完整性的基础。
维度属性可作为查询约束、分组、报表标识的主要来源。对查询或报表请求来说,属性以词或词组加以区分。
维度提供数据的入口点,提供所有DW/BI分析的最终标识和分组。
概述
维度模型表示每个业务过程包含事实表,事实表存储事件的数值化度量,围绕事实表的是多个维度表,维度表包含事件发生时实际存在的文本环境。这种类似星状的结构通常称为星型连接。