0%

数仓变化维度的建设实践

简介

之前的文章中概述了如何建设数仓的变化维度,这里对建设变化维度进行实践,本文建设了全国的地市维度,由于地市归属区域有时会变化,这里采用了最常用的类型2来处理,也就是俗称的拉链表.

爬取数据

我采用java和selenium 代码
https://github.com/liushprofessor/hase_repository/blob/master/create_data/src/main/java/com/liu/City.java
将爬取的数据先存入hbase在导入到Phoenix中,关于如何创建hbase表和将hbase数据和Phoenix做关联这里就不做重复描述,可参考之前的文章,Phoenix中的示例数据如下,这里采用的是星型模型,星型模型在数仓中是最常用的维度数据模型,相比于关系型数据库的雪花模型,其存储了冗余数据,来减少连表的查询,在数据仓库中存在大量数据,我们要尽量避免连表来加快数据的分析速度。数据仓库中所有事实表的数据需要拉平(在同一纬度),这也要求我们的维度表也在在同一维度,比如下面数据中台湾省(台),并不存在地和县,我们在处理的时候就需要强行将台湾数据拉平,人为给di和xian字段创建台湾,如果不给维度拉平,那么在数据在做group by分析时会导致数据的不准确,应该用日期类型比较合适但是我这里为了方便演示就使用了字符串

ID CODE SHENG DI XIAN BEGIN_DATE END_DATE
1595152366153 1 北京市(京) 北京市 东城区 1999-01-01 2999-01-01
1595152366332 2 北京市(京) 北京市 西城区 1999-01-01 2999-01-01
1595152366393 3 北京市(京) 北京市 朝阳区 1999-01-01 2999-01-01
1595152366921 4 北京市(京) 北京市 丰台区 1999-01-01 2999-01-01
1595152366974 5 北京市(京) 北京市 石景山区 1999-01-01 2999-01-01
1595152367027 6 北京市(京) 北京市 海淀区 1999-01-01 2999-01-01
1595152367081 7 北京市(京) 北京市 门头沟区 1999-01-01 2999-01-01
1595152367356 8 北京市(京) 北京市 房山区 1999-01-01 2999-01-01
1595152367413 9 北京市(京) 北京市 通州区 1999-01-01 2999-01-01
1595152367473 10 北京市(京) 北京市 顺义区 1999-01-01 2999-01-01
1595152367529 11 北京市(京) 北京市 昌平区 1999-01-01 2999-01-01
1595152367591 12 北京市(京) 北京市 大兴区 1999-01-01 2999-01-01
1595152367657 13 北京市(京) 北京市 怀柔区 1999-01-01 2999-01-01
1595152367719 14 北京市(京) 北京市 平谷区 1999-01-01 2999-01-01
1595152367774 15 北京市(京) 北京市 密云区 1999-01-01 2999-01-01
1595152367827 16 北京市(京) 北京市 延庆区 1999-01-01 2999-01-01
1595153354199 2849 台湾省(台) 台湾省(台) 台湾省(台) 1999-01-01 2999-01-01

分析数据

这里我建设了一张用户表其数据如下,其模拟了一张用户维度表,其有一个地区维度和我们之前的地区维度做关联

ID NAME AREA_PK
1 mike 1016
2 jake 1016
3 tom 1016
4 liu 1019
  • 连表查询用户地市信息
1
select t.*,t1.sheng,t1.di,t1.xian from f_user t inner join d_area t1 on t.area_pk=t1.code;
ID NAME AREA_PK T1.SHENG T1.DI T1.XIAN
1 mike 1016 福建省(闽) 福州市 闽侯县
2 jake 1016 福建省(闽) 福州市 闽侯县
3 tom 1016 福建省(闽) 福州市 闽侯县
4 liu 1019 福建省(闽) 福州市 闽清县
5 li 1046 福建省(闽) 泉州市 鲤城区
  • 维度信息上卷查询福州市下的所有用户信息
1
select t.*,t1.sheng,t1.di,t1.xian from f_user t inner join d_area t1 on t.area_pk=t1.code where t1.di='福州市';
ID NAME AREA_PK T1.SHENG T1.DI T1.XIAN
1 mike 1016 福建省(闽) 福州市 闽侯县
2 jake 1016 福建省(闽) 福州市 闽侯县
3 tom 1016 福建省(闽) 福州市 闽侯县
4 liu 1019 福建省(闽) 福州市 闽清县
  • 统计分析福州县下的用户数量
1
select t1.xian ,count(*) from f_user t inner join d_area t1 on t.area_pk=t1.code group by t1.xian;
T1.XIAN COUNT(1)
闽侯县 3
闽清县 1
鲤城区 1

维度的变化

现在我们来模拟维度变化,假设上面的数据今天闽侯县变成了闽侯区,这里我们应用上面创建的拉链表来处理维度的变化

修改原来的数据
ID CODE SHENG DI XIAN BEGIN_DATE END_DATE
1595152702922 1016 福建省(闽) 福州市 闽侯县 1999-01-01 2999-01-01

我们修改end_date字段,将结束日期修改成今天 2020-07-19 ,对应Phoenix为

1
upsert into  d_area (id,end_date) values('1595152702922','2020-07-19');

新增数据

我们这里新增数据,保存原来的code,但是将begin_date ,和end_date修改成现在的时间

1
upsert into d_area(id,code,sheng,di,xian,begin_date,end_date) values('1595158956','1016','福建省(闽)','福州市','闽侯区','2020-07-20','2999-01-01');
ID CODE SHENG DI XIAN BEGIN_DATE END_DATE
1595152702922 1016 福建省(闽) 福州市 闽侯县 1999-01-01 2020-07-19
1595158956 1016 福建省(闽) 福州市 闽侯区 2020-07-20 2999-01-01

查询分析

现在我们我们再次执行上面用户分析地市的查询语句,现在查询出的数据已经是变更后的数据

1
select t.*,t1.sheng,t1.di,t1.xian from f_user t inner join d_area t1 on t.area_pk=t1.code where end_date>'2020-07-19' and code='1016';
ID NAME AREA_PK T1.SHENG T1.DI T1.XIAN
1 mike 1016 福建省(闽) 福州市 闽侯区
2 jake 1016 福建省(闽) 福州市 闽侯区
3 tom 1016 福建省(闽) 福州市 闽侯区

由于我们有了时间字段,我们在日期更改后还能对历史维度进行分析

1
select t.*,t1.sheng,t1.di,t1.xian from f_user t inner join d_area t1 on t.area_pk=t1.code where end_date<'2020-07-20' and code='1016';