简介
之前的文章中概述了如何建设数仓的变化维度,这里对建设变化维度进行实践,本文建设了全国的地市维度,由于地市归属区域有时会变化,这里采用了最常用的类型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';
|