第一章.Hive实战
1.需求描述
需求描述
统计硅谷影音视频网站的常规指标,各种TopN指标
- 统计视频观看数top10
- 统计视频类别热度top10(类别热度:类别下的总视频数)
- 统计出视频观看数最高的20个视频的所属类别以及类别包含top20视频的个数
- 统计视频观看数top50所关联视频的所属类别Rank
- 统计每个类别中的视频热度top10,以Music为例
- 统计每个类别视频观看数top10
- 统计上传视频最多的用户top10以及他们上传视频观看次数在前20的视频
2.数据结构
1.视频表
| 字段 | 备注 | 详细描述 |
|---|---|---|
| videoid | 视频唯一id(string) | 11位字符串 |
| uploader | 视频上传者(string) | 上传视频的用户名 |
| age | 视频年龄(int) | 视频在平台上的整数天 |
| category | 视频类别(Array(string)) | 上传视频指定的视频分类 |
| length | 视频长度(int) | 整形数字标识的视频长度 |
| views | 观看次数(int) | 视频被浏览的次数 |
| rate | 视频评分(double) | 满分5分 |
| Ratings | 流量(int) | 视频的流量,整形数字 |
| conments | 评论数(int) | 一个视频的整数评论数 |
| relatedid | 相关视频id(Array(string)) | 相关视频的id,最多20个 |
2.用户表
| 字段 | 备注 | 字段类型 |
|---|---|---|
| uploader | 上传者用户名 | string |
| videos | 上传视频数 | int |
| friends | 朋友数量 | int |
3.准备工作
需要准备的表
- 创建外部数据表 : gulivideo_ori, gulivideo_user_ori
- 创建最终表: gulivideo_orc,gulivideo_user_ori
# 创建外部数据表1. 上传原始数据到HDFShadoop fs -mkdir -p /gulivideo/videohadoop fs -mkdir -p /gulivideo/userhadoop fs -put /home/atguigu/data/user/user.txt /gulivideo/userhadoop fs -put /home/atguigu/data/video/*.txt /gulivideo/video2. 创建外部数据表:gulivideo_oricreate external table gulivideo_ori(videoId string,uploader string,age int,category array<String>,length int,views int,rate float,ratings int,comments int,relatedId array<String>)row format delimited fields terminated by '\t'collection items terminated by '&'stored as textfilelocation '/gulivideo/video';3. 创建外部数据表: gulivideo_user_oricreate external table gulivideo_user_ori(uploader string,Videos int,friends int)row format delimited fields terminated by '\t'stored as textfilelocation '/gulivideo/user';
# 创建orc存储格式带snappy压缩的管理表1. gulivideo_orccreate table gulivideo_orc(videoId string,uploader string,age int,category array<string>,length int,views int,rate float,ratings int,comments int,relatedId array<string>)stored as orctblproperties("orc.compress"="SNAPPY");2. gulivideo_user_orccreate table gulivideo_user_orc(uploader string,videos int,friends int)row format delimitedfields terminated by "\t"stored as orctblproperties("orc.compress"="SNAPPY");
# 向表中插入数据insert into table gulivideo_orc select * from gulivideo_ori;insert into table gulivideo_user_orc select * from gulivideo_user_ori;
4.业务分析
需求一: 统计视频观看数Top10
思路 : 使用order by 按照views字段做一个全局排序即可,同时我们设置只显示前10条
select videoId,`views`from gulivideo_orcorder by `views` desclimit 10;
需求二:统计视频类别热度Top10(类别热度:类别下的总视频数)
思路:
- 即统计每个类别有多少个视频,显示出包含视频最多的前10个类别
- 需要按照类别group by聚合,然后count组内的videoId个数即可
- 因为当前表结构为: 一个视频对应一个或多个类别,所以如果要group by类别,需要先将类别进行列转行(炸开),然后再进行count 即可
- 最终按照热度排序,显示前10条
select t1.category_name,count(t1.videoId) cvfrom(select videoId,category_namefrom gulivideo_orclateral view explode(category) lv as category_name) t1group by t1.category_nameorder by cv desclimit 10;
需求三: 统计出视频观看数最高的20个视频的所属类别以及类别包含Top20视频的个数
思路:
- 求出观看数前20的视频信息(主要是类别)
- 在第一步的结果下,求出观看数前20的视频的类别,需要炸开(列转行),形成新字段category_name
- 在第二步的结果下,按照炸开的视频类别category_name 分组,然后统计组内的个数category_count
select t2.category_name,count(t2.videoId)from(select t1.videoId,category_namefrom(select videoId, `views` ,categoryfrom gulivideo_orcorder by `views` desclimit 20) t1lateral view explode (t1.category) lv as category_name) t2group by t2.category_name;
需求四: 统计视频观看数top50的视频所关联视频的所属类别排序
思路:
- 先找出观看数前50的视频信息(主要是求出关联视频)
- 炸开第一步求出的关联视频array,形成一个新字段new_relatedid
- 用第二步求出的结果集的new_relatedid和gulivideo_orc表进行join,求出new_relatedid的类别
- 炸开第三部结果中的category,形成新字段category_name
- 在第四部的结果上,按照category_name分组,然后求出每组的个数 category_count
- 在第五步的基础上,对category_count进行排序,利用开窗函数
-- 6.使用rank函数对count_number进行排序(要的是排名)select t6.category_name,t6.count_number,rank()over(order by t6.count_number desc)from (-- 5.将类别分组并统计出其数量select t5.category_name, count(t5.category_name) count_numberfrom (-- 4.将关联视频的类别炸开select category_namefrom (-- 3.将相关视频的表和视频表进行关联(relatedid_name和videoid)select t2.relatedid_name, t3.videoid, t3.categoryfrom (--2.将关联的视频炸开select t1.relatedid, relatedid_namefrom (--1.获取top50的视频select videoid, `views`, relatedidfrom gulivideo_orcorder by `views` desclimit 50) t1lateral view explode(t1.relatedid) lv as relatedid_name) t2join gulivideo_orc t3on t2.relatedid_name = t3.videoid) t4lateral view explode(t4.category) lv as category_name) t5group by t5.category_name) t6;
需求五: 统计每个类别中的视频热度(视频观看数) Top10,以Music为例
思路 :
- 要想统计Music类别中的视频热度Top10,需要先找到Music类别,那么就需要将category炸开形成新的字段category_name
- 然后通过category_name过滤”Music”分类的所有视频信息,按照视频观看数倒序排序
select t1.category_name,t1.`views`from(select `views`,category_namefromgulivideo_orclateral view explode(category) lv as category_name) t1where t1.category_name = 'Music'order by t1.`views` desclimit 10;
需求六: 统计每个类别视频观看数Top10
思路:
- 把原始表中的类别炸开,形成新字段category_name
- 按照炸开的类别字段category_name分区,按照视频观看数views倒序排序进行开窗,求出每个类别下的所有视频的观看次数排名
- 按照rk字段对全表进行where过滤,求出每个类别观看数Top10
select t2.videoId,t2.`views`,t2.category_name,t2.r_numberfrom(select t1.videoId,t1.`views`,t1.category_name,rank() over(partition by t1.category_name order by t1.`views` desc ) r_numberfrom(select videoid,category_name,`views`fromgulivideo_orclateral view explode(category) lv as category_name) t1)t2where t2.r_number <= 10;
需求七: 统计上传视频最多的用户Top10,以及他们上传的视频观看次数在前20 的视频
此需求的后半段”他们上传的视频观看次数在前20的视频”说的含糊不清,有以下两种约定
约定一: 取Top10中所有人上传的视频的前20
思路:
- 去用户表gulivideo_user_orc 求出上传视频最多的10个用户
- 关联gulivideo_orc表,求出这10个用户上传的所有视频,按照观看数求前20
# 上传视频最多的用户Top10select uploader,videosfromgulivideo_user_orcorder by videos desclimit 10;# 他们上传的视频观看次数在前20的视频select t1.uploader,t2.`views`from(select uploader,videosfromgulivideo_user_orcorder by videos desclimit 10) t1 join gulivideo_orc t2on t1.uploader = t2.uploaderorder by `views` desclimit 20;
约定二: 取Top10中每个人上传视频的前20
思路:
- 去用户表gulivideo_user_orc求出上传视频最多的10个用户
- 关联gulivideo_orc表,求出这10个用户上传的所有视频的id,视频观看次数,还要按照uploader分区,views倒序排序,求出每个uploader的上传的视频的观看排名r_number
- 在第二步的基础上,按照rk进行where过滤,求出r_number< =20的数据
select t4.uploader,t4.`views`,t4.r_numberfrom(select t3.`views`,t3.uploader,rank() over(partition by t3.uploader order by `views` desc) r_numberfrom(select t1.uploader,t2.`views`from(select uploader,videosfrom gulivideo_user_orcorder by videos desclimit 10) t1join gulivideo_orc t2on t1.uploader = t2.uploader) t3) t4where t4.r_number <= 20;
第二章.企业级优化
详情见avi视频
