数仓(十)从0到1简单搭建加载数仓DWS层
数仓(一)简介数仓,OLTP和OLAP
数仓(二)关系建模和维度建模
数仓(三)简析阿里、美团、网易、恒丰银行、马蜂窝5家数仓分层架构
数仓(四)数据仓库分层
数仓 (五) 元数据管理系统解析
数仓(六)从0到1简单搭建数仓ODS层(埋点日志 + 业务数据)
数仓(七)从0到1简单搭建加载数仓DIM层以及拉链表处理
数仓(八)从0到1简单搭建加载数仓DWD层(用户行为日志数据解析)
上一次我们讲解了DWD层(关于用户交易等业务数据)的搭建、解析加载。这节我们讲解DWS层关于各个主题的加工和使用,这层是宽表聚合值,是各个事实表的聚合值。
一、DWS层概念回顾
在第四章我们对DWS层做了概述,现在我们再来回顾一下。
DWS(Data Warehouse Service)
使轻度汇总层,从ODS层中对用户的行为做一个初步的汇总,抽象出来一些通用的维度:时间、ip、id,并根据这些维度做一些统计值。
这里做轻度的汇总会让以后的计算更加的高效,如:统计各个主题对象计算7天、30天、90天的行为, 应对特殊需求(例如,购买行为,统计商品复购率)会快很多不必走ODS层反复拿数据做加工。
这层以分析的主题对象作为建模驱动,基于上层的应用和产品的指标需求,构建公共粒度的汇总指标事实表,以宽表化手段物理化模型。构建命名规范、口径一致的统计指标,为上层提供公共指标,建立汇总宽表、明细事实表。
服务于 DWT 层的主题宽表,以及一些业务明细数据。
涉及的主题包括:访客主题、用户主题、商品主题、优惠券主题、活动主题、地区主题等。
二、DWS层用户主题加工
用户主题记录某一个用户在某一天的汇总行为。
1、首先我们看一下我们需要统计或者说加工的指标,一共是25个左右;
login_count` BIGINT COMMENT '登录次数',
`cart_count` BIGINT COMMENT '加入购物车次数',
`favor_count` BIGINT COMMENT '收藏次数',
`order_count` BIGINT COMMENT '下单次数',
`order_activity_count` BIGINT COMMENT '订单参与活动次数',
`order_activity_reduce_amount` DECIMAL(16,2) COMMENT '订单减免金额(活动)',
`order_coupon_count` BIGINT COMMENT '订单用券次数',
`order_coupon_reduce_amount` DECIMAL(16,2) COMMENT '订单减免金额(使用优惠券)',
`order_original_amount` DECIMAL(16,2) COMMENT '订单单原始金额',
`order_final_amount` DECIMAL(16,2) COMMENT '订单总金额',
`payment_count` BIGINT COMMENT '支付次数',
`payment_amount` DECIMAL(16,2) COMMENT '支付金额',
`refund_order_count` BIGINT COMMENT '退单次数',
`refund_order_num` BIGINT COMMENT '退单件数',
`refund_order_amount` DECIMAL(16,2) COMMENT '退单金额',
`refund_payment_count` BIGINT COMMENT '退款次数',
`refund_payment_num` BIGINT COMMENT '退款件数',
`refund_payment_amount` DECIMAL(16,2) COMMENT '退款金额',
`coupon_get_count` BIGINT COMMENT '优惠券领取次数',
`coupon_using_count` BIGINT COMMENT '优惠券使用(下单)次数',
`coupon_used_count` BIGINT COMMENT '优惠券使用(支付)次数',
`appraise_good_count` BIGINT COMMENT '好评数',
`appraise_mid_count` BIGINT COMMENT '中评数',
`appraise_bad_count` BIGINT COMMENT '差评数',
`appraise_default_count` BIGINT COMMENT '默认评价数',
`order_detail_stats` array<struct<sku_id:string,sku_num:bigint,order_count:bigint,activity_reduce_amount:decimal(16,2),coupon_reduce_amount:decimal(16,2),original_amount:decimal(16,2),final_amount:decimal(16,2)>> COMMENT '下单明细统计'
2、根据指标建表
这里我们搭建DWS层级表,XXXX就是上面指标的字段。
DROP TABLE IF EXISTS dws_user_action_daycount;
CREATE EXTERNAL TABLE dws_user_action_daycount
( XXXXX ......
)
COMMENT '每日用户行为'PARTITIONED BY (`dt` STRING)
STORED AS PARQUETLOCATION
'/warehouse/gmall/dws/dws_user_action_daycount/'
TBLPROPERTIES ("parquet.compression"="lzo");
3、逐个计算指标
3.1 login_count 登录次数
这个指标简单,根据dwd层,dwd_page_log表可以直接计算;
select dt, user_id, count(*) login_count
from dwd_page_log
where user_id is not null
and last_page_id is null
group by dt,user_id
3.2 cart_count 加入购物车次数;
favor_count 收藏次数;
这两个指标也是很简单,直接根据dwd层,dwd_action_log表中获取
SQL实现
select dt, user_id, sum(if(action_id='cart_add',1,0)) cart_count,sum(if(action_id='favor_add',1,0)) favor_count
from dwd_action_log
where user_id is not null
and action_id in ('cart_add','favor_add')
group by dt,user_id
3.3 order_count 下单次数;
order_activity_count 订单参与活动次数;
order_activity_reduce_amount 订单减免金额(活动);
order_coupon_count 订单用券次数;
order_coupon_reduce_amount 订单减免金额(使用优惠券);
order_original_amount 订单单原始金额;
order_final_amount 订单总金额;
订单表的几个指标相对也很简单,直接根据dwd层,dwd_order_info表中获取
SQL实现
select date_format(create_time,'yyyy-MM-dd') dt, user_id, count(*) order_count, sum(if(activity_reduce_amount>0,1,0)) order_activity_count, sum(if(coupon_reduce_amount>0,1,0)) order_coupon_count, sum(activity_reduce_amount) order_activity_reduce_amount, sum(coupon_reduce_amount) order_coupon_reduce_amount, sum(original_amount) order_original_amount, sum(final_amount) order_final_amount
from dwd_order_info
group by date_format(create_time,'yyyy-MM-dd'),user_id
3.4 payment_count'支付次数',
payment_amount'支付金额',
SQL实现
selectdate_format(callback_time,'yyyy-MM-dd') dt,user_id,count(*) payment_count,sum(payment_amount) payment_amount
from dwd_payment_info
group by date_format(callback_time,'yyyy-MM-dd'),user_id
3.5 refund_order_count 退单次数',
refund_order_num 退单件数',
refund_order_amount '退单金额',
SQL实现
selectdate_format(create_time,'yyyy-MM-dd') dt,user_id,count(*) refund_order_count,sum(refund_num) refund_order_num,sum(refund_amount) refund_order_amount
from dwd_order_refund_info
group by date_format(create_time,'yyyy-MM-dd'),user_id
3.6refund_payment_count '退款次数',
refund_payment_num '退款件数',
refund_payment_amount '退款金额',
ri表示上述退单中间表,rp表示退款中间表;然后做左外链接取交集;
SQL实现
selectdate_format(callback_time,'yyyy-MM-dd') dt,rp.user_id,count(*) refund_payment_count,sum(ri.refund_num) refund_payment_num,sum(rp.refund_amount) refund_payment_amountfrom(selectuser_id,order_id,sku_id,refund_amount,callback_timefrom dwd_refund_payment)rpleft join(selectuser_id,order_id,sku_id,refund_numfrom dwd_order_refund_info)rion rp.order_id=ri.order_idand rp.sku_id=rp.sku_idgroup by date_format(callback_time,'yyyy-MM-dd'),rp.user_id
3.7coupon_get_count '优惠券领取次数',
coupon_using_count '优惠券使用(下单)次数',
coupon_used_count '优惠券使用(支付)次数',
SQL实现
selectcoalesce(coupon_get.dt,coupon_using.dt,coupon_used.dt) dt,coalesce(coupon_get.user_id,coupon_using.user_id,coupon_used.user_id) user_id,nvl(coupon_get_count,0) coupon_get_count,nvl(coupon_using_count,0) coupon_using_count,nvl(coupon_used_count,0) coupon_used_count
from
(selectdate_format(get_time,'yyyy-MM-dd') dt,user_id,count(*) coupon_get_countfrom dwd_coupon_usewhere get_time is not nullgroup by user_id,date_format(get_time,'yyyy-MM-dd')
)coupon_get
full outer join
(selectdate_format(using_time,'yyyy-MM-dd') dt,user_id,count(*) coupon_using_countfrom dwd_coupon_usewhere using_time is not nullgroup by user_id,date_format(using_time,'yyyy-MM-dd')
)coupon_using
on coupon_get.dt=coupon_using.dt
and coupon_get.user_id=coupon_using.user_id
full outer join
(selectdate_format(used_time,'yyyy-MM-dd') dt,user_id,count(*) coupon_used_countfrom dwd_coupon_usewhere used_time is not nullgroup by user_id,date_format(used_time,'yyyy-MM-dd')
)coupon_used
on nvl(coupon_get.dt,coupon_using.dt)=coupon_used.dt
and nvl(coupon_get.user_id,coupon_using.user_id)=coupon_used.user_id
)
3.8appraise_good_count '好评数',
appraise_mid_count '中评数',
appraise_bad_count '差评数',
这个数值直接从dwd层,dwd_comment_info表里面取sum值
SQL实现
selectdate_format(create_time,'yyyy-MM-dd') dt,user_idsum(if(appraise='1201',1,0)) appraise_good_count,sum(if(appraise='1202',1,0)) appraise_mid_count,sum(if(appraise='1203',1,0)) appraise_bad_count,sum(if(appraise='1204',1,0)) appraise_default_count
from dwd_comment_info
group by date_format(create_time,'yyyy-MM-dd'),user_id
4、完成首日和每日加载
汇总SQL后做首日装载,分区是动态分区dt
insert overwrite table dws_user_action_daycount partition(dt)
selectcoalesce(tmp_login.user_id,tmp_cf.user_id,tmp_order.user_id,tmp_pay.user_id,tmp_ri.user_id,tmp_rp.user_id,tmp_comment.user_id,tmp_coupon.user_id,tmp_od.user_id),nvl(login_count,0),nvl(cart_count,0),nvl(favor_count,0),XXXX,
每日装载,dt = 当前时间分区;
insert overwrite table dws_user_action_daycount partition(dt='2020-06-15')
selectcoalesce(tmp_login.user_id,tmp_cf.user_id,tmp_order.user_id,tmp_pay.user_id,tmp_ri.user_id,tmp_rp.user_id,tmp_comment.user_id,tmp_coupon.user_id,tmp_od.user_id),nvl(login_count,0),nvl(cart_count,0),nvl(favor_count,0),nvl(order_count,0),
这样我们就完成了关于用户主题的DWS层的汇聚值的计算。
请读者参考后完成以下主题:
访客主题、商品主题、优惠券主题、活动主题、地区主题等,每日装载和首装载的SQL。
总结:
数仓DWS层的概念、作用;
DWS层的宽表聚合值是各个事实表的聚合值,怎么样加工和计算?
数仓(十)从0到1简单搭建加载数仓DWS层相关推荐
- 十分钟用Windows服务器简单搭建DHCP中继代理!!
十分钟用Windows服务器简单搭建DHCP中继代理!! 一.什么是中继代理? 大家都知道DHCP分配地址都需要用到IP广播,但是广播是不能在两个网段之间进行 ...
- “存储区更新、插入或删除语句影响到以外的行数(0)。实体在加载后可能被修改或删除”如何解决
做项目的时候,我们的try... catch语句捕捉到这种异常,我们该如何解决呢? 之所以出现这样的异常,是因为我们用实体对象在接收页面的参数时,并没有接收到实体对象的主键,所以我们要在视图那里获取到 ...
- html canvas直线进度条,js+HTML5 canvas 实现简单的加载条(进度条)功能示例
本文实例讲述了js+HTML5 canvas 实现简单的加载条(进度条)功能.分享给大家供大家参考,具体如下: www.jb51.net canvas实现加载条动画 /* * 获取canvas, ca ...
- 最简单的加载器免杀思路
本文首发于先知社区:https://xz.aliyun.com/t/9385 这部分源代码开放:https://github.com/MrWQ/HanGuang 最简单的加载器免杀思路 将加载器的变量 ...
- 基于iSroll 5.0实现的上拉加载和下拉刷新插件
Updownload.js 基于iSroll 5.0实现的上拉加载和下拉刷新插件 移动端效果比较好,开发者工具打开后,需要刷新下页面. [演示地址:] https://chenyk2016.githu ...
- 数仓(六)从0到1简单搭建数仓ODS层(埋点日志 + 业务数据)
数仓(一)简介数仓,OLTP和OLAP 数仓(二)关系建模和维度建模 数仓(三)简析阿里.美团.网易.恒丰银行.马蜂窝5家数仓分层架构 数仓(四)数据仓库分层 数仓(五)元数据管理系统解析 最近工作一 ...
- 十四、猜码游戏: 每一轮里,程序随机生成两个数字,一个是码数,范围:0到5,一个是猜数,范围:码数到10。用户输入两个数字,也分为码数和猜数。 若这一轮程序的猜数等于两个码数之和,输出“电脑胜”,若
import random a=int(input('请输入码数')) b=int(input('请输入猜数')) i=random.randint(0,6) j=random.randint(i,1 ...
- 数仓实战|两步搞定Hive数据加载到Greenplum
如果说Hive是离线数仓的代表,那么Greenplum就是MPP数据库的代表.在离线数仓的年代,以Hive为核心的数据仓库席卷数据仓库市场,几乎成为了离线数仓的代名词.但是Hive的查询能力非常弱,通 ...
- Android OpenGLES2.0(十四)——Obj格式3D模型加载
转自:http://blog.csdn.net/junzia/article/details/54300202 在博主<OpenGLES系列>文章中,最开始的几篇讲的就是OpenGL世界中 ...
最新文章
- 算法与数据结构(Java解八皇后问题)
- 计算机怎么模拟人,计算机能不能模拟人的思维?
- __VA_ARGS__宏
- java wordcount程序_WordCount程序(java)
- PHP从零开始--字段修饰符数据操作SQL语言
- LOJ#2145. 「SHOI2017」分手是祝愿
- 盘点提高程序员技术的5个免费编程网站,你知道几个?
- USACO-Section1.3 Name That Number (遍历与字符串比较)
- java路由方法_Linux添加路由的方法
- eslint常规语法检
- 天线发射功率计算公式_天线基本知识及应用―链路及空间无线传播损耗计算
- python在线编辑器手机-App Store 上的quot;Python AI - 代码编辑器”
- Vue学习之路---No.5(分享心得,欢迎批评指正)
- 搜索和内容生态的关系
- 用VBS脚本实现软件定条件开启
- Idempotent Consumer
- javascript网页设计期末作业 购物网站
- 2020.4.11普及C组 Loan Repayment【纪中】【二分】
- 计算机二级系统班C语言讲义,计算机二级C语言2017辅导讲义:C语言基本知识
- 开源世界里的重要理念:上游优先(UpStream First)
热门文章
- 基于java的消防系统
- 合理的网页设计具有哪些特征
- 【云原生进阶之容器】第一章Docker核心技术1.6节——UnionFS
- 【历史上的今天】1 月 15 日:维基百科上线;信息安全大师出生;英特尔推出 Viiv
- Ubuntu 14.04 更换源(官方源——阿里源)
- 工控随笔_10_西门子_WinCC的VBS脚本_01_基础入门
- Android Dialer模块联系人搜索
- android模拟器 出错:X Error of failed request: BadRequest (invalid request code or no such operation)
- Python 小小爬虫练手,爬取自己的IP
- 【医学影像】几个医学影像专业一定要知道的网站