数据仓库模型与缓慢变化维度技术深度剖析-DW商业环境实战
本套系列博客从真实商业环境抽取案例进行总结和分享,并给出大数据商业实战指导,请持续关注本套博客。版权声明:本套大数据商业实战系列归作者(秦凯新)所有,禁止转载,欢迎学习。
- 秦凯新的技术社区-大数据商业实战系列全集目录
- DW商业环境实战-数据仓库模型与缓慢变化维度技术深度剖析
1 数据仓库模型概述
2 数据仓库分层模型
- STAGE 层
STAGE 层作为数据缓冲层,主要负责采集不同类型的业务系统数据并保存一定期限内的相关业务数据,完成不同类型数据源的统一临时存储,同时避免 ETL 操作对业务系统性能造成影响,STAGE 层数据在数据结构、数据之间的逻辑关系上都与业务系统基本保持一致。
- ODS 数据层
ODS(Operational Data Store)层数据来源于 STAGE 层,它的数据经过了对 STAGE 层数据的清洗,包括编码表去重、去空、垃圾数据过滤、数据类型规则化等。ODS存储了运营系统(如OLTP(联机事务处理)系统)近实时的详细数据。
另外 ODS 作为 DW 和 STAGE 层的桥梁,也可以实现指标一致性的管理,将不同系统不同部门相同指标的定义及指标数据按照业务规则取其一,保证不同源数据的数据一致性,也可以满足用户对明细数据的查询要求,直接从ODS层获取明细数据进行分析。
- DWD 数据层
DWD(Data Warehouse Detail)层数据是将 ODS 层数据根据数据清洗规则,经过质量检查、数据清洗、转换、标准化后,形成符合质量要求的公共数据中心,有的也称为 ODS层,是业务层与数据仓库的隔离层
把 ODS 数据表结构改变成项目主题数据仓库的表结构,对 DWD 层的所有表添加了代理键,标准化了业务系统编码类型不统一的问题,建立了数据仓库维度表和事实表的关联体系,也为缓慢变化维的实现奠定了基础。
- DWC 数据层
DWC(Data Warehouse Center)层主要管理固化报表的数据存储,数据主要来源于 DWD 层,根据前台所需数据建立物理模型,使用 ETL 抽取 DWD 层数据推送给 DWC 层,这样显著减少前台应用直接关联 DWD 层查询明细数据的成本,提高平台数据获取的速度。
- DWB数据层:
DWB数据层(data warehouse base)表示 基础数据层,存储的是客观数据,一般用作中间层,可以认为是大量指标的数据层。
- DWS数据层:
DWS数据层 (data warehouse service)表示 服务数据层,基于DWB上的基础数据,整合汇总成分析某一个主题域的服务数据,一般是宽表。
- DM 数据层
DM(Data Mart)层即数据集市,将指标与维度建立物理模型组成数据集市,这是 OLAP 的数据基础。该层实现了合并不同系统的数据源来满足面向主题的业务需求,它的建模是终端用户驱动的,也是由业务需求驱动的。按主题,维度及 KPI 指标对 DM 层进行模型设计、建模,DM 层数据是将 DWD 层数据进行进一步整合、转换、汇总、计算等 ETL 操作处理获取的。
DW数据分层,由下到上关系依次为 STAGE->ODS->DWD->DWB->DWS
3 企业级数据仓库总体设计
4 OLTP和OLAP的区别
4.1 联机事务处理OLTP(on-line transaction processing)
主要是执行基本日常的事务处理,比如数据库记录的增删查改。比如在银行的一笔交易记录,就是一个典型的事务。
4.2 OLTP的特点有:
- 实时性要求高。比如银行异地汇款,秒级到账的节奏。
- 数据量不是很大,生产库上的数据量一般不会太大,而且会及时做相应的数据处理与转移。
- 交易一般是确定的,比如银行存取款的金额肯定是确定的,所以OLTP是对确定性的数据进行存取
- 高并发,并且要求满足ACID原则。比如两人同时操作一个银行卡账户,比如大型的购物网站秒杀活动时上万的QPS请求。
4.3 联机分析处理OLAP
联机分析处理OLAP(On-Line Analytical Processing) 是数据仓库系统的主要应用,支持复杂的分析操作,侧重决策支持,并且提供直观易懂的查询结果。典型的应用就是复杂的动态的报表系统。
4.4 OLAP的特点有:
- 实时性要求不是很高,比如最常见的应用就是天级更新数据,然后出对应的数据报表。
- 数据量大,因为OLAP支持的是动态查询,所以用户也许要通过将很多数据的统计后才能得到想要知道的信息,例如时间序列分析等等,所以处理的数据量很大;
- OLAP系统的重点是通过数据提供决策支持,所以查询一般都是动态,自定义的。所以在OLAP中,维度的概念特别重要。一般会将用户所有关心的维度数据,存入对应数据平台。
4.5 总结:
OLAP是数据仓库的核心部心,所谓数据仓库是对于大量已经由OLTP形成的数据的一种分析型的数据库,用于处理商业智能、决策支持等重要的决策信息;数据仓库是在数据库应用到一定程序之后而对历史数据的加工与分析,读取较多,更新较少。
5 缓慢变化维度技术案例精讲
5.1原始数据准备
- 新增了第6条数据
- 删除了第2条数据
- 修改了第1条数据的name列、cty列和st列(name列按SCD2处理,cty列和st列按SCD1处理)
- 修改了第4条数据的cty列和st列(按SCD1处理)
- 修改了第5条数据的name列(按SCD2处理)
5.2 建立过渡表
DROP TABLE IF EXISTS tbl_stg;CREATE TABLE tbl_stg (id INT,name STRING,cty STRING,st STRING)ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';
复制代码
5.3 建立维度表渡表
DROP TABLE IF EXISTS tbl_dim;CREATE TABLE tbl_dim (sk INT,id INT,name STRING,cty STRING,st STRING,version INT,effective_date DATE,expiry_date DATE)CLUSTERED BY (id) INTO 8 BUCKETSSTORED AS ORC TBLPROPERTIES ('transactional'='true');
复制代码
5.4 向维表中添加数据
INSERT INTO tbl_dimSELECTROW_NUMBER() OVER (ORDER BY tbl_stg.id) + t2.sk_max,tbl_stg.*,1,CAST('1900-01-01' AS DATE),CAST('2200-01-01' AS DATE)from tbl_stg CROSS JOIN (SELECT COALESCE(MAX(sk),0) sk_max FROM tbl_dim) t2;
复制代码
5.5 更新过渡表中的数据
drop table tbl_stg;LOAD DATA LOCAL INPATH '/root/opendir/test-data/aa.txt' INTO TABLE tbl_stg;
复制代码
5.6 设置日期变量
SET hivevar:pre_date = DATE_ADD(CURRENT_DATE(),-1);SET hivevar:max_date = CAST('2200-01-01' AS DATE);
复制代码
5.7 name列的缓慢变化维scd2-->向维度表装载更新后的数据设置已删除记录和SCD2的过期(测试时间为20180904)
1,张三,US,CA -->scd2 scd1
2,李四,US,CB -->删除
3,王五,CA,BB -->没变
4,赵六,CA,BC -->scd1
5,老刘,AA,AA -->scd21,张,U,C
3,王五,CA,BB
4,赵六,AC,CB
5,刘,AA,AA
6,老杨,DD,DDUPDATE tbl_dim
SET expiry_date = ${hivevar:pre_date}
WHERE sk IN
(SELECT a.sk FROM (
SELECT sk,id,name FROM tbl_dim WHERE expiry_date = ${hivevar:max_date}) a LEFT JOIN tbl_stg b ON a.id=b.id
WHERE b.id IS NULL OR a.name<>b.name);tbl_dim.sk tbl_dim.id tbl_dim.name tbl_dim.cty tbl_dim.st tbl_dim.version tbl_dim.effective_date tbl_dim.expiry_date1 1 张三 US CA 1 1900-01-01 2018-09-03 -->过期2 2 李四 US CB 1 1900-01-01 2018-09-03 -->过期(记录删除) 3 3 王五 CA BB 1 1900-01-01 2200-01-014 4 赵六 CA BC 1 1900-01-01 2200-01-01 5 5 老刘 AA AA 1 1900-01-01 2018-09-03 -->过期
复制代码
5.8 处理SCD2新增行(name列的缓慢变化维scd2)
INSERT INTO tbl_dimSELECTROW_NUMBER() OVER (ORDER BY t1.id) + t2.sk_max,t1.id,t1.name,t1.cty,t1.st,t1.version,t1.effective_date,t1.expiry_dateFROM(SELECTt2.id id,t2.name name,t2.cty cty,t2.st st,t1.version + 1 version,${hivevar:pre_date} effective_date,${hivevar:max_date} expiry_dateFROM tbl_dim t1 INNER JOIN tbl_stg t2ON t1.id=t2.id AND t1.name<>t2.name AND t1.expiry_date = ${hivevar:pre_date}LEFT JOIN tbl_dim t3 ON t1.id = t3.id AND t3.expiry_date = ${hivevar:max_date}WHERE t3.sk IS NULL) t1CROSS JOIN(SELECT COALESCE(MAX(sk),0) sk_max FROM tbl_dim) t2;tbl_dim.sk tbl_dim.id tbl_dim.name tbl_dim.cty tbl_dim.st tbl_dim.version tbl_dim.effective_date tbl_dim.expiry_date1 1 张三 US CA 1 1900-01-01 2018-09-03 6 1 张 U C 2 2018-09-03 2200-01-01 --->新增行2 2 李四 US CB 1 1900-01-01 2018-09-03 3 3 王五 CA BB 1 1900-01-01 2200-01-014 4 赵六 CA BC 1 1900-01-01 2200-01-015 5 老刘 AA AA 1 1900-01-01 2018-09-03 7 5 刘 AA AA 2 2018-09-03 2200-01-01 --->新增行
复制代码
5.9 处理SCD1-->因为hive的update还不支持子查询,所以这里使用了一个临时表存储需要更新的记录。
用先delete再insert代替update,因为SCD1本身就不保存历史数据,所以这里更新维度表里的所有cty或st改变的记录,而不是仅仅更新当前版本的记录
DROP TABLE IF EXISTS tmp;
CREATE TABLE tmp AS
SELECT a.sk,a.id,a.name,b.cty,b.st,a.version,a.effective_date,a.expiry_date FROM tbl_dim a, tbl_stg b
WHERE a.id=b.id AND (a.cty <> b.cty OR a.st <> b.st);
DELETE FROM tbl_dim WHERE sk IN (SELECT sk FROM tmp);
INSERT INTO tbl_dim SELECT * FROM tmp;原始数据
1,张三,US,CA -->scd2 scd1
2,李四,US,CB -->删除
3,王五,CA,BB -->没变
4,赵六,CA,BC -->scd1
5,老刘,AA,AA -->scd2过度业务数据
1,张,U,C
3,王五,CA,BB
4,赵六,AC,CB
5,刘,AA,AA
6,老杨,DD,DD
复制代码
修改了第4条数据的cty列和st列(按SCD1处理)
6 1 张 U C 2 2018-09-03 2200-01-01 -->scd2 scd1
1 1 张三 U C 1 1900-01-01 2018-09-03 -->scd2 scd1
2 2 李四 US CB 1 1900-01-01 2018-09-03 -->删除
3 3 王五 CA BB 1 1900-01-01 2200-01-01 -->没变
4 4 赵六 AC CB 1 1900-01-01 2200-01-01 -->scd1
5 5 老刘 AA AA 1 1900-01-01 2018-09-03 -->scd2
7 5 刘 AA AA 2 2018-09-03 2200-01-01 -->scd2
复制代码
5.10 除SCD1和SCD2外,处理新增记录
INSERT INTO tbl_dimSELECTROW_NUMBER() OVER (ORDER BY t1.id) + t2.sk_max,t1.id,t1.name,t1.cty,t1.st,1,${hivevar:pre_date},${hivevar:max_date}FROM(SELECT t1.* FROM tbl_stg t1 LEFT JOIN tbl_dim t2 ON t1.id = t2.idWHERE t2.sk IS NULL) t1CROSS JOIN(SELECT COALESCE(MAX(sk),0) sk_max FROM tbl_dim) t2;1,张三,US,CA -->scd2 scd1
2,李四,US,CB -->删除
3,王五,CA,BB -->没变
4,赵六,CA,BC -->scd1
5,老刘,AA,AA -->scd21,张,U,C
3,王五,CA,BB
4,赵六,AC,CB
5,刘,AA,AA
6,老杨,DD,DD6 1 张 U C 2 2018-09-03 2200-01-01 -->scd2 scd1
1 1 张三 U C 1 1900-01-01 2018-09-03 -->scd2 scd1
2 2 李四 US CB 1 1900-01-01 2018-09-03 -->删除
3 3 王五 CA BB 1 1900-01-01 2200-01-01 -->没变
4 4 赵六 AC CB 1 1900-01-01 2200-01-01 -->scd1
5 5 老刘 AA AA 1 1900-01-01 2018-09-03 -->scd2
7 5 刘 AA AA 2 2018-09-03 2200-01-01 -->scd2
8 6 老杨 DD DD 1 2018-09-03 2200-01-01 -->新增
复制代码
6 用户内容推荐之行变列以及列变行数据仓库技术
drop table if exists articles;create external table articles(article_id STRING,url STRING,kws array< STRING >)ROW FORMAT DELIMITEDFIELDS TERMINATED BY ','COLLECTION ITEMS TERMINATED BY '|'LOCATION '/hivepeixun/articles';
复制代码
drop table if exists user_actions;复合数组元素,拆分split
create external table user_actions(user_id STRING,article_id STRING,ts STRING
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
LOCATION '/hivepeixun/users';collect_set去重功能:
select user_id, collect_set(article_id) from user_actions group by user_id;collect_list没有去重功能:用户分组后,进行文章汇总成集合:
select user_id, collect_list(article_id) from user_actions group by user_id;
:
select user_id,sort_array(collect_list(article_id)) from user_actions group by user_id;拆开某条字段,一条数据变成多条记录,没有关联时为空的就过滤掉了:select article_id,kw from articles2 lateral view explode(kws) t as kw;select a.* , b.kw from user_actions as a left outer join (select article_id, kw from articles lateral view explode(kws) t as kw) b on (a.article_id =b.article_id)
复制代码
select a.user_id , b.kw , count(1) as weight from user_actions as a
left outer join (select article_id, kw from articles lateral view explode(kws) t as kw)
b on (a.article_id =b.article_id) group by a.user_id ,b.kw order by a.user_id ,weight desc;
复制代码
6 用户内容推荐需求挖掘
未完待续
7 最后
本节内容主要探讨了数据仓库模型与缓慢变化维度技术深度剖析,本文参考了经典案例,并进行重新编排,内容有所变化,可能部分截图来自github公开源码,部分是我的测试案例,如有雷同某位大神私有内容,请直接留言于我,我来重新修正案例。
秦凯新 于深圳
数据仓库模型与缓慢变化维度技术深度剖析-DW商业环境实战相关推荐
- 聊聊数据仓库中的缓慢变化维度(SCD)
虽然我的主业是实时计算和批量计算,并不是数仓,但是在日常工作中绝对少不了与数仓打交道.并且我也算是参与过离线数仓建设的,维度建模的基础还是不能忘.本文就作为一篇抄书笔记吧. SCD简介 顾名思义,缓慢 ...
- 分布式协调组件ZooKeeper的技术理论剖析-综合组件环境实战
本套技术专栏是作者(秦凯新)平时工作的总结和升华,通过从真实商业环境抽取案例进行总结和分享,并给出商业应用的调优建议和集群环境容量规划等内容,请持续关注本套博客.QQ邮箱地址:1120746959@q ...
- 数据仓库缓慢变化维度SCD?你想知道的都在这里
点击上方蓝色字体,选择"设为星标" 回复"资源"获取更多资源 大数据技术与架构 点击右侧关注,大数据开发领域最强公众号! 大数据真好玩 点击右侧关注,大数据真好 ...
- 漫谈数据仓库之SCD(缓慢变化维度)
0x01 什么是SCD? SCD(Slowly Changing Dimensions),中文一般翻译成"缓慢变化维". 缓慢变化维的提出是因为在现实世界中,维度的属性并不是静态的 ...
- 数据仓库(9)数仓缓慢变化维度数据的处理
数据仓库的重要特点之一是反映历史变化,所以如何处理维度的变化是维度设计的重要工作之一.缓慢变化维的提出是因为在现实世界中,维度的属性并不是静态的,它会随着时间的流逝发生缓慢的变化,与数据增长较为快 ...
- 数据仓库之缓慢变化维度处理
当维度数据发生变化时,有多种处理方式,一般会用缓慢变化维类型2来处理,也就是当维度属性发生变化时,新生成1行,同时添加 开始日期,结束日期 . 比如: 业务系统中的 用户表: userId mobil ...
- 缓慢变化维度(SCD)
SCD简介 SCD Type 0: Retain Original(维持原状) SCD Type 1: Overwrite(覆盖) SCD Type 2: Add New Row(添加新行) SCD ...
- 一种基于SparkSQL的Hive数据仓库拉链表缓慢变化维(SCD2+SCD1)的示例实现
背景 Hive 实现缓慢变化维,没有使用事务表的更新和删除操作(最新版本Hive已经支持,但需要Server/Client做相应配置,Hive实现的事务还有一定的局限性) Hive 自身的SQL使用M ...
- 数仓缓慢变化维SCD深度讲解
维度缓慢变化维SCD(Slowly Changing Dimensions)一些维度表的数据不是静态的,而是会随着时间而缓慢地变化(这里的缓慢是相对事实表而言,事实表数据变化的速度比维度表快,如果还不 ...
- 云原生钻石课程 | 第1课:容器运行时技术深度剖析
点击上方"程序猿技术大咖",关注并选择"设为星标" 回复"加群"获取入群讨论资格! 本篇文章来自<华为云云原生王者之路训练营>钻 ...
最新文章
- 【技术分享总结】—设计模式
- Python学习小结---粗略列表解析
- 反射获取构造方法并使用【应用】
- Tomcat 比 nio 、aio性能更好的apr介绍
- oracle中修改数据库实例监听的ip和端口
- IOT(22)---NB-IoT、LoRa产业组织格局
- 附件计算器中的MC、MR、MS、M+作用
- 老人 android 游戏,其乐融融 -- 给父母玩的游戏 #iOS #Android
- jQuery2.x源码解析(设计篇)
- sqlserver 还原bak文件 查看不到_SQL还原数据库备份方法
- 添加内核驱动模块(5)(mydriver.c+ Konfig+Makefile )
- 单元测试中测试用例的设计方法
- 元器件型号: ATMEGA328P-AU
- 7. 堆(宋红康笔记)
- 作为空降领导,该如何做?
- 删除后别人的微信号变成wxid_腾讯开放微信号修改,一年一次,方法简单
- 使用js脚本实现微信定时发送信息
- 2018北大数学夏令营游记
- 学术规范与论文写作(期末考试答案)(方便检索版)
- Solr Server服务器端安装配置
热门文章
- Eclipse-导入maven项目
- 【学堂在线数据挖掘:理论方法笔记】第五天(3.29)
- MATLAB随机数生成器
- python_datetime
- 在centos7中安装flutter,执行flutter --version时显示flutter的版本为v0.0.0 unknown
- CSS学习总结(6)——定位与布局
- ArcGIS学习总结(九)——将.kml转换为.shp
- ERDAS 安装完成之后如何打开软件新建工程
- PHP结合redis实现秒杀活动大并发
- Flutter BuildOwner之inactive Elements浅析