Hive电商数仓实战

本文涉及的产品
云原生数据仓库AnalyticDB MySQL版,基础版 8ACU 100GB 1个月
简介: 以电商数据为基础,详细介绍数据处理流程,结合hive数仓、spark开发采用多种方式实现大数据分析。

项目描述


以电商数据为基础,详细介绍数据处理流程,结合hive数仓、spark开发采用多种方式实现大数据分析。


数据源可通过日志采集、爬虫、数据库中取得,经过数据清洗转换导入数据仓库,通过数仓中数据分析得到数据总结,用于企业决策。本项目基于以下表类进行电商数仓分析,分为orders(用户行为表),trains(订单表),products(商品表),departments(品类表),order_products__prior(用户历史行为表),实现多维度数仓分析。


数据仓库概念:

数据仓库(Data WareHouse),简写DW,为企业决策制定过程,提供所有系统数据支持的战略集合,通过对数据仓库中的数据分析,帮助企业改进业务流程,控制成本,提高产品质量。


数据仓里不是数据的最终目的地,而是为数据最终目的地做好准备,这些准备对数据:清洗,转义,分类,重组,合并,拆分,统计

b22c72693395da5af8fbd47aedd9caf7_watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3d3d3p5ZGNvbQ==,size_16,color_FFFFFF,t_70.png



一、数据表


1.orders.csv (数据仓库中定位:用户行为表)

order_id:订单号
user_id:用户id
eval_set:订单的行为(历史产生的或者训练所需要的)
order_number:用户购买订单的先后顺序
order_dow:order day of week ,订单在星期几进行购买的(0-6)
order_hour_of_day:订单在哪个小时段产生的(0-23)
days_since_prior_order:表示后一个订单距离前一个订单的相隔天数
order_id,user_id,eval_set,order_number,order_dow,order_hour_of_day,days_since_prior_order
2539329,1,prior,1,2,08,
2398795,1,prior,2,3,07,15.0
473747,1,prior,3,3,12,21.0
2254736,1,prior,4,4,07,29.0
431534,1,prior,5,4,15,28.0

2.trains.csv

order_id:订单号
product_id:商品ID
add_to_cart_order:加入购物车的位置
reordered:这个订单是否重复购买(1 表示是 0 表示否)
order_id,product_id,add_to_cart_order,reordered
1,49302,1,1
1,11109,2,1
1,10246,3,0
1,49683,4,0

3.products.csv(数据仓库定位:商品维度表)

product_id:商品ID
product_name:商品名称
aisle_id:货架id
department_id:该商品数据属于哪个品类,日用品,或者生活用品等
product_id,product_name,aisle_id,department_id
1,Chocolate Sandwich Cookies,61,19
2,All-Seasons Salt,104,13
3,Robust Golden Unsweetened Oolong Tea,94,7
4,Smart Ones Classic Favorites Mini Rigatoni With Vodka Cream Sauce,38,1
5,Green Chile Anytime Sauce,5,13


4.departments.csv(品类维度表)

department_id:部门id, 品类id
department: 品类名称
department_id,department
1,frozen
2,other
3,bakery

5.order_products__prior.csv(用户历史行为数据)

order_id,product_id,add_to_cart_order,reordered
2,33120,1,1
2,28985,2,1
2,9327,3,0
[/infobox]


二、数据分析


1.将orders,trains建表,将数据导入到hive中?

建orders表


create table badou.orders(
order_id string
,user_id string
,eval_set string
,order_number string
,order_dow string
,order_hour_of_day string
,days_since_prior_order string)
row format delimited fields terminated by ','
lines terminated by '\n'


1.加载本地数据  overwrite 覆盖 into 追加

load data local inpath '/badou20/03hive/data/orders.csv'
overwrite into table orders
select * from orders limit 10;
hive> select * from orders limit 10;
OK
order_id user_id eval_set order_number order_dow order_hour_of_day days_since_prior_order
2539329 1 prior 1 2 08
2398795 1 prior 2 3 07 15.0
473747 1 prior 3 3 12 21.0
2254736 1 prior 4 4 07 29.0
431534 1 prior 5 4 15 28.0
2.加载hdfs数据(无local)
load data inpath '/orders.csv'
overwrite into table orders
建trains表
create table badou.trains(
order_id string,
product_id string,
add_to_cart_order string,
reordered string)
row format delimited fields terminated by ','
lines terminated by '\n'
load data local inpath '/badou20/03hive/data/order_products__train.csv' 
overwrite into table trains


2.如何去掉表中第一行的脏数据?(原数据第一行为列名,导入时要删除)

方式一:shell命令

思想:在load数据之前,针对异常数据进行处理  sed '1d' orders.csv


head -10 orders.csv > tmp.csv
cat tmp.csv
sed '1d' tmp.csv > tmp_res.csv
cat tmp_res.csv
Linux sed 命令 | 菜鸟教程


方式二:HQL (hive sql)

insert overwrite table badou.orders
select * from orders where order_id !='order_id'
insert overwrite table badou.trains
select * from trains where order_id !='order_id'


3.每个(groupby分组)用户有多少个订单(count(distinct))?

user_id order_id => user_id order_cnt


分组:针对不同类别进行归类,常用的 group by


结果: order count => order_cnt


select user_id, ordert_cnt 两列


第二列写法下面都可


, count(distinct order_id) order_cnt
--,count(*) order_cnt
--,count(1) order_cnt
--,count(order_id) order_cnt


完整语句:


 
         


结果:

两个job,Total MapReduce CPU Time Spent: 1 minutes 4 seconds 370 msec
133983 100
181936 100
14923 100
55827 100

4.每个用户一个订单平均是多少商品?

我今天购买了2个order,一个是10个商品,另一个是4个商品


(10+4)一个订单对应多少个商品 / 2


结果:一个用户购买了几个商品=7


a.先使用 priors 表,计算一个订单有多少个商品?  对应 10,4


注意:使用聚合函数(count、sum、avg、max、min )的时候要结合group by 进行使用


select
order_id,count(distinct product_id) pro_cnt
from priors
group by order_id
limit 10;


b.将priors表和order表通过order_id进行关联,将步骤a中商品数量带到用户上面


结果:用户对应的商品量


select
od.user_id, t.pro_cnt
from orders od
inner join (
select
order_id, count(1) as pro_cnt
from priors
group by order_id
limit 10000
) t
on od.order_id=t.order_id
limit 10;

c.针对步骤b,进行用户对应的商品量 sum求和

select
od.user_id, sum(t.pro_cnt) as sum_prods
from orders od
inner join (
select
order_id, count(1) as pro_cnt
from priors
group by order_id
limit 10000
) t
on od.order_id=t.order_id
group by od.user_id
limit 10;


d.计算平均


结果:用户的商品数量  / 用户的订单数量


select
od.user_id
, sum(t.pro_cnt) / count(1) as sc_prod
, avg(pro_cnt) as avg_prod
from orders od
inner join (
select
order_id, count(1) as pro_cnt
from priors
group by order_id
limit 10000
) t
on od.order_id=t.order_id
group by od.user_id
limit 10;
inner join : 多个表进行内连接
where :提取我们关注的数据


5.每个用户在一周中的购买订单的分布(列转行) ? dow  => day of week  0-6 代表周一到周日

order_dow
orderday, pro_cnt
2020-12-19  1000000
2020-12-18  1000010
user_id, dow0, dow1, dow2, dow3,dow4,dow5,dow6
1         0     3      2    2    4    0    0
2         0     5      5    2    1    1    0


注意:实际开发中,一定是最先开始使用小批量数据进行验证,验证代码逻辑的正确性,然后全量跑!!


user_id order_dow
1    0   sum=0+1=1
1    0   sum=1+1=2
1    1
2    1


方式一:


select
user_id
, sum(case when order_dow='0' then 1 else 0 end) dow0
, sum(case when order_dow='1' then 1 else 0 end) dow1
, sum(case when order_dow='2' then 1 else 0 end) dow2
, sum(case when order_dow='3' then 1 else 0 end) dow3
, sum(case when order_dow='4' then 1 else 0 end) dow4
, sum(case when order_dow='5' then 1 else 0 end) dow5
, sum(case when order_dow='6' then 1 else 0 end) dow6
from orders
-- where user_id in ('1','2','3')
group by user_id

方式一:


select
user_id
, sum(if( order_dow='0',1,0)) dow0
, sum(if( order_dow='1',1,0)) dow1
, sum(if( order_dow='2',1,0)) dow2
, sum(if( order_dow='3',1,0)) dow3
, sum(if( order_dow='4',1,0)) dow4
, sum(if( order_dow='5',1,0)) dow5
, sum(if( order_dow='6',1,0)) dow6
from orders
where user_id in ('1','2','3')
group by user_id


抽样验证结果的准确性:


user_id dow0    dow1    dow2    dow3    dow4    dow5    dow6
1         0      3       2        2       4       0       0
2         0      6       5        2       1       1       0

课堂需求:某个时间段查看每个用户购买了哪些商品?

分析:

user_id, product_id
orders : order_id, user_id
trains:order_id, product_id
select
ord.user_id, tr.product_id
from orders ord
inner join trains tr
on ord.order_id=tr.order_id
where order_hour_of_day = '10'
limit 10
CREATE TABLE `udata`(
`user_id` string,
`item_id` string,
`rating` string,
`timestamp` string)
ROW FORMAT DELIMITED


注意:timestamp关键字,建表使用 ``881250949 -- > 1997-12-04 23:55:49


在udata表通过timestamp进行先后顺序的标记区分:


需求: 在推荐时候,想知道距离现在最近 或者最远的时间是什么时候?

select
max(`timestamp`) max_timestamp, min(`timestamp`) min_timestamp
from udata
max_timestamp   min_timestamp
893286638   874724710


需求:得到某一个用户具体的评论天数,结果该用户在哪些天比较活跃,可能①用户确实很活跃  ② 用户可能存在刷单的情况,刷评价

user_id ['2020-12-19','2020-12-18',....]
24*60*60
collect_list : 不去重,将所有的user_id进行收集
select collect_list('1,2,3')
select
user_id, collect_list(cast(days as int)) as day_list
from
(select
user_id
, (cast(893286638 as bigint) - cast(`timestamp` as bigint)) / (24*60*60) * rating as days
from udata
) t
group by user_id
limit 10;


需求: 用户购买的商品数量大于100的数量有哪些?

union all: 数据合并,但是数据不去重, 注意 union  all 前后的字段类型和字段个数必须保持一致


union:数据合并并且去重


方式一:


select
user_id, count(distinct product_id) pro_cnt
from
(
-- 订单训练数据  场景 整合两个新老系统数据
select
a.user_id,b.product_id
from orders as a
left join trains b
on a.order_id=b.order_id
union all
-- 订单历史数据
select
a.user_id,b.product_id
from orders as a
left join priors b
on a.order_id=b.order_id
) t
group by user_id
having pro_cnt >= 100
limit 10;
方式二:引入 with关键字,作用:涉及到逻辑很复杂,嵌套关系特别多使用,提高代码阅读性,便于排查问题
通过with修饰的可以理解为临时表或者临时数据集
with user_pro_cnt_tmp as (
select * from
(-- 订单训练数据
select
a.user_id,b.product_id
from orders as a
left join trains b
on a.order_id=b.order_id
union all
-- 订单历史数据
select
a.user_id,b.product_id
from orders as a
left join priors b
on a.order_id=b.order_id
) t
)
--, order_pro_tmp as (
--), ....
select
user_id
, count(distinct product_id) pro_cnt
from user_pro_cnt_tmp
group by user_id
having pro_cnt >= 100
limit 10;
[/infobox





相关实践学习
阿里云云原生数据仓库AnalyticDB MySQL版 使用教程
云原生数据仓库AnalyticDB MySQL版是一种支持高并发低延时查询的新一代云原生数据仓库,高度兼容MySQL协议以及SQL:92、SQL:99、SQL:2003标准,可以对海量数据进行即时的多维分析透视和业务探索,快速构建企业云上数据仓库。 了解产品 https://www.aliyun.com/product/ApsaraDB/ads
目录
相关文章
|
2月前
|
存储 SQL 监控
数据中台架构解析:湖仓一体的实战设计
在数据量激增的数字化时代,企业面临数据分散、使用效率低等问题。数据中台作为统一管理与应用数据的核心平台,结合湖仓一体架构,打通数据壁垒,实现高效流转与分析。本文详解湖仓一体的设计与落地实践,助力企业构建统一、灵活的数据底座,驱动业务决策与创新。
|
6月前
|
分布式计算 运维 监控
Dataphin离线数仓搭建深度测评:数据工程师的实战视角
作为一名金融行业数据工程师,我参与了阿里云Dataphin智能研发版的评测。通过《离线数仓搭建》实践,体验了其在数据治理中的核心能力。Dataphin在环境搭建、管道开发和任务管理上显著提效,如测试环境搭建从3天缩短至2小时,复杂表映射效率提升50%。产品支持全链路治理、智能提效和架构兼容,帮助企业降低40%建设成本,缩短60%需求响应周期。建议加强行业模板库和移动适配功能,进一步提升使用体验。
|
4月前
|
SQL 分布式计算 大数据
大数据新视界 --大数据大厂之Hive与大数据融合:构建强大数据仓库实战指南
本文深入介绍 Hive 与大数据融合构建强大数据仓库的实战指南。涵盖 Hive 简介、优势、安装配置、数据处理、性能优化及安全管理等内容,并通过互联网广告和物流行业案例分析,展示其实际应用。具有专业性、可操作性和参考价值。
大数据新视界 --大数据大厂之Hive与大数据融合:构建强大数据仓库实战指南
|
5月前
|
存储 消息中间件 Java
抖音集团电商流量实时数仓建设实践
本文基于抖音集团电商数据工程师姚遥在Flink Forward Asia 2024的分享,围绕电商流量数据处理展开。内容涵盖业务挑战、电商流量建模架构、流批一体实践、大流量任务调优及总结展望五个部分。通过数据建模与优化,实现效率、质量、成本和稳定性全面提升,数据质量达99%以上,任务性能提升70%。未来将聚焦自动化、低代码化与成本优化,探索更高效的流批一体化方案。
377 12
抖音集团电商流量实时数仓建设实践
|
6月前
|
SQL 分布式计算 关系型数据库
基于云服务器的数仓搭建-hive/spark安装
本文介绍了在本地安装和配置MySQL、Hive及Spark的过程。主要内容包括: - **MySQL本地安装**:详细描述了内存占用情况及安装步骤,涉及安装脚本的编写与执行,以及连接MySQL的方法。 - **Hive安装**:涵盖了从上传压缩包到配置环境变量的全过程,并解释了如何将Hive元数据存储配置到MySQL中。 - **Hive与Spark集成**:说明了如何安装Spark并将其与Hive集成,确保Hive任务由Spark执行,同时解决了依赖冲突问题。 - **常见问题及解决方法**:列举了安装过程中可能遇到的问题及其解决方案,如内存配置不足、节点间通信问题等。
基于云服务器的数仓搭建-hive/spark安装
|
7月前
|
SQL 缓存 数据处理
数据无界、湖仓无界,Apache Doris 湖仓一体典型场景实战指南(下篇)
Apache Doris 提出“数据无界”和“湖仓无界”理念,提供高效的数据管理方案。本文聚焦三个典型应用场景:湖仓分析加速、多源联邦分析、湖仓数据处理,深入介绍 Apache Doris 的最佳实践,帮助企业快速响应业务需求,提升数据处理和分析效率
374 3
数据无界、湖仓无界,Apache Doris 湖仓一体典型场景实战指南(下篇)
|
数据采集 大数据
大数据实战项目之电商数仓(二)
大数据实战项目之电商数仓(二)
310 0
|
10月前
|
消息中间件 Java Kafka
实时数仓Kappa架构:从入门到实战
【11月更文挑战第24天】随着大数据技术的不断发展,企业对实时数据处理和分析的需求日益增长。实时数仓(Real-Time Data Warehouse, RTDW)应运而生,其中Kappa架构作为一种简化的数据处理架构,通过统一的流处理框架,解决了传统Lambda架构中批处理和实时处理的复杂性。本文将深入探讨Kappa架构的历史背景、业务场景、功能点、优缺点、解决的问题以及底层原理,并详细介绍如何使用Java语言快速搭建一套实时数仓。
989 4
|
SQL 数据库 HIVE
hive数仓 ods层增量数据导入
根据业务需求,当表数据量超过10万条时采用增量数据导入,否则全量导入。增量导入基于`create_date`和`modify_date`字段进行,并确保时间字段已建立索引以提升查询效率。避免在索引字段上执行函数操作。创建增量表和全量表,并按日期进行分区。首次导入全量数据,后续每日新增或变更数据保存在增量表中,通过全量表与增量表的合并保持数据一致性。
431 12
|
SQL 数据采集 分布式计算
Hive 数仓及数仓设计方案
数仓整合企业数据,提供统一出口,用于数据治理。其特点包括面向主题集成和主要支持查询操作。数仓设计涉及需求分析(如咨询老板、运营人员和行业专家)、确定主题指标(如电商的转化率)、数据标准设定、规模与成本计算、技术选型(如Hadoop生态组件)以及数据采集和操作。设计流程涵盖从理解需求到实施SQL函数和存储过程的全过程。
389 3

热门文章

最新文章