Hive-简易教程
数据分析篇
Hive是一个HDFS上的sql执行引擎,它将sql语句转化为Hadoop上的map-reduce任务来执行。由于是写sql,所以使用Hive进行数据分析的好处是没有什么额外的学习成本,但是它是批量式处理的,可能会比较慢。本文将通过几个案例来简单介绍如何使用Hive。
样例数据
随机生成一批订单数据(order_id, price, tag, order_date)
1 | from random import randint |
存储数据到Hive
1 | hive> create table test_order_sample |
案例一
统计出近一周每天成功支付的订单总数,gmv,客单价
1 | hive> select order_date,count(*),round(sum(price),2),round(avg(price),2) |
案例二
统计出近一周每天成功支付 及支付失败 各自的订单总数,gmv,客单价
1 | select order_date, |
count函数和if条件组合,而不是两个sql join
案例三
挑选出近一周gmv>1000并且订单量>2单的卖家ID及其订单
1 | hive> select seller_id,collect_set(order_id) |
常用函数
聚合相关函数
collect_set(c_1)
在使用group by之后只能select出group key以及相关的统计数字,但也可以以集合的形式select出任何其他的非group key,比如按卖家ID聚合之后又想查看在这个卖家下单的买家ID:sellect collect_set(buyer_id) from t group by seller_id。
collect_list(c_1)
与collect_set类似,元素可重复
explode(c_1)
explode函数可以把一个array类型的数据扁平化。比如,现在每行是一个seller_id集合,使用explode可以扁平化为每行一个seller_id。但explode不可以直接与group by一起使用,比如我想按某些条件筛选一些卖家然后在查看该店铺的买家的情况:select explode(b.buyer_ids) from (select collect_set(buyer_id) as buyer_ids from t group by seller_id) b;
时间函数
unix_timestamp()
当前时间
from_unixtime(timestamp, format)
将系统时间戳转化为人可读的数据格式 如:select from_unixtime(unix_timestamp(), ‘yyyy-MM-dd’);
date_sub(string startdate, int days)
求几天前的日期
其它
nvl(v1, v2)
nvl函数用于处理null值,当一个字段是null时,这个字段和其它字段进行算术运算时的结果依然为null。这时可以使用这个函数为值可能为null的字段赋予一个默认值,即v2.
instr(str1, ‘xxx’)
判断字符串’xxx’是否出现在str1中,如果str1是null或者不存在xxx返回值都是0
size(a1)
返回数组a1的大小
union_all()
合并两个查询结果,但结果的列数需要一致!!!
自定义UDF篇
简介
实现自定义的UDF需要编写Java程序,然后在Hive客户端中加载相关Jar并注册函数后就可以使用了。
示例
实现转化IP地址为二进制格式
1 | import org.apache.hadoop.hive.ql.exec.UDF; |
打包
mvn package
加载
从本地加载
hive> add jar xxx.jar;
从hdfs加载并注册
create [temporary] function unmask_ip as ‘example.IPUnMasker’ using jar ‘hdfs:///user/zzz/jars/hive_udf-1.0.0.jar’;
删除函数
drop funciton unmask_ip;
使用udf
select unmask_ip(‘112.117.138.216’);
附录
pom依赖
1 | <dependencies> |
相关链接
https://cwiki.apache.org/confluence/display/Hive/HivePlugins
数据存储篇
hive是hdfs上的数据仓库,能够将一个个大文件有效地管理起来,并对其进行统计分析。数据仓库看待数据的方式与常见的数据库是完全不同的,它的最小粒度是文件而不是单条数据。hive一般在hdfs上的路径为/user/hive/warehouse,而hive中的数据库(如demo)的路径就是/user/hive/warehouse/demo.db,在往下就是表的路径如:/user/hive/warehouse/demo.db/test。管理hive上的数据分为两部分:定义数据以及操纵数据。
基本命令
切换数据库:use 数据库名;
显示当前数据库中的所有变:show tables;
查看表结构:desc 表名;
查看建表语句:show create table 表名;
数据定义语句(DDL)
创建表
完整语句
1 | CREATE [TEMPORARY] [EXTERNAL] TABLE [IF NOT EXISTS] [db_name.]table_name -- (Note: TEMPORARY available in Hive 0.14.0 and later) |
- hive可以创建临时表[temporary],临时表在当前会话结束时(如关闭hive客户端)会被自动删除。
- hive可以外部的映射表[external],即hive并不将这些数据存储在自己的hdfs路径中,而只保存表的元数据。这样hive便可访问更多的数据源,如hbase。
- hive可以直接将select语句的结果保存为一个表:create table t2 as select * from t1;
- hive的基本单元是文件,那么在创建表的时候可以指定文件中每行数据的分隔符,即按该分割符分割后即为表的各列:create table t(c1 string, c2 string) row format delimited fields terminated by ‘\t’。
- hive中的表就是hdfs上的一个路径,在创建表时可以在其下继续创建文件目录,这样的好处就是在查询时可以只访问一些指定的目录来提高性能。create table t1(id string) partitioned by (year string, month string),这样t1路径下就是year的文件夹,而year的每个值路径下还有month文件夹,如图所示:
修改表
表重命名:alter table 原表名 rename to 新表名
删除分区:alter table xx drop partition (xx=’’)
数据操纵语言(DML)
加载数据
1)从本地加载: load data local inpath ‘data/t1’ into table t1;
2)从HDFS转移:load data inpath ‘/user/hive/project/data1’ into table xxx;
杂项篇
设置打印列名
set hive.cli.print.header=true;
设置动态分区
set hive.exec.dynamic.partition.mode=nonstrict;
hive cli默认的动态分区数量可能小于实际的分区数量,这时需要更改参数:
set hive.exec.dynamic.partitions=xxx;
set hive.exec.max.dynamic.partitions.pernode=xxx;
查看hive日志
hive -hiveconf hive.root.logger=INFO,console
以脚本方式执行并传递参数
test.sql:
select distinct seller_id from order where order_date=’${hiveconf:ORDER_DATE}’
hive -hiveconf ORDER_DATE=”xxx” -f test.sql
客户端中设置参数
set para=xxx
select a from b where c>${hiveconf:xxx}
客户端中执行hadoop命令
hive> dfs -ls /
评论系统未开启,无法评论!