Hive高级操作

目录

1.Hive数据类型

1.1.原子数据类型

1.2.复杂数据类型

1.3.示例演示

1.3.1.array

1.3.2.map

1.3.3.struct

1.3.4.uniontype

2.视图

3.Hive函数

3.1.Hive内置函数

3.2.Hive自定义函数UDF

3.2.1.一个简单的UDF示例

3.2.2.Json数据解析UDF开发

3.2.3.Tranform实现

4.Hive特殊分隔符处理

4.1.使用RegexSerDe通过正则表达式来抽取字段


1.Hive数据类型

1.1.原子数据类型

数据类型 长度 备注
Tinyint 1字节的有符号整数 -128~127
SmallInt 1字节的有符号整数 -32768~32767
Int 4字节的有符号整数 -2147483648~2147483647
BigInt 8字节的有符号整数 -9223372036854775808~9223372036854775807
Boolean 布尔类型,true或者false true、false
Float 单精度浮点数  
Double 双精度浮点数  
String 字符串  
TimeStamp 整数 支持Unixtimestamp,可以达到纳秒精度

1.Hive 支持日期类型(老版本不支持),在 Hive 里日期一般都是用字符串来表示的,而常用的日期格式转化操作则是通过自定义函数进行操作,当然也可以直接指定为日期类型。
2.Hive 是用 Java 开发的,Hive 里的基本数据类型和 java 的基本数据类型也是一一对应的,除了 String 类型。
3.有符号的整数类型:TINYINT、SMALLINT、INT 和 BIGINT 分别等价于 Java 的 Byte、Short、Int 和 Long 原子类型,它们分别为 1 字节、2 字节、4 字节和 8 字节有符号整数。
4.Hive 的浮点数据类型 FLOAT 和 DOUBLE,对应于 Java 的基本类型 Float 和 Double 类型。
5.Hive 的 BOOLEAN 类型相当于 Java 的基本数据类型 Boolean。
6.Hive 的 String 类型相当于数据库的 Varchar 类型,该类型是一个可变的字符串,不过它不能声明其中最多能存储多少个字符,理论上它可以存储 2GB 的字符数。

1.2.复杂数据类型

复杂数据类型包括数组(ARRAY)、映射(MAP)和结构体(STRUCT),具体如下所示:

说明

ARRAY:ARRAY 类型是由一系列相同数据类型的元素组成,这些元素可以通过下标来访问。比如有一个 ARRAY 类型的变量 fruits,它是由['apple','orange','mango']组成,那么我们可以通过 fruits[1]来访问元素 orange,因为 ARRAY 类型的下标是从 0 开始的 。
MAP:MAP 包含 key->value 键值对,可以通过 key 来访问元素。比如”userlist”是一个 map类 型 , 其 中 username 是 key , password 是 value ; 那 么 我 们 可 以 通 过userlist['username']来得到这个用户对应的 password。
STRUCT:STRUCT 可以包含不同数据类型的元素。这些元素可以通过”点语法”的方式来得到所需要的元素,比如 user 是一个 STRUCT 类型,那么可以通过 user.address 得到这个用户的地址。

示例

CREATE TABLE student(
name STRING,
favors ARRAY,
scores MAP,
 address STRUCT

 ROW FORMAT DELIMITED 
 FIELDS TERMINATED BY '\t' 
 COLLECTION ITEMS TERMINATED BY ';'
MAP KEYS TERMINATED BY ':' ;

说明:
1.字段 name 是基本类型,favors 是数组类型,可以保存很多爱好,scores 是映射类型,可以保存多个课程的成绩,address 是结构类型,可以存储住址信息。
2.ROW FORMAT DELIMITED 是指明后面的关键词是列和元素分隔符的
3.FIELDS TERMINATED BY 是字段分隔符
4.COLLECTION ITEMS TERMINATED BY 是元素分隔符(Array 中的各元素、Struct 中的各元素、Map 中的 key-value 对之间)
5.MAP KEYS TERMINATED BY 是 Map 中 key 与 value 的分隔符
6.LINES TERMINATED BY 是行之间的分隔符
8.STORED AS TEXTFILE 指数据文件上传之后保存的格式

总结:在关系型数据库中,我们至少需要三张表来定义,包括学生基本表、爱好表、成绩表;但在 Hive 中通过一张表就可以搞定了。也就是说,复合数据类型把多表关系通过一张表就可以实现了。

1.3.示例演示

1.3.1.array

建表语句
create table person1(name string,work_locations array)
row format delimited fields terminated by '\t'
collection items terminated by ',';
数据
huangbo beijing,shanghai,tianjin,hangzhou
xuzheng changchu,chengdu,wuhan
wangbaoqiang dalian,shenyang,jilin
导入数据
load data local inpath '/home/hadoop/person.txt' into table person1;
查询语句
Select * from person1;
Select name from person1;
Select work_locations from person1;
Select work_locations[0] from person1;

1.3.2.map

建表语句
create table score(name string, scores map)
row format delimited fields terminated by '\t'
collection items terminated by ','
map keys terminated by ':';
数据
huangbo yuwen:80,shuxue:89,yingyu:95
Stay hungry Stay foolish -- http://blog.csdn.net/zhongqi2513
xuzheng yuwen:70,shuxue:65,yingyu:81
wangbaoqiang yuwen:75,shuxue:100,yingyu:75
导入数据
load data local inpath '/home/hadoop/score.txt' into table score;
查询语句
Select * from score;
Select name from score;
Select scores from score;
Select s.scores['yuwen'] from score s;

1.3.3.struct

建表语句:
create table structtable(id int,course struct)
row format delimited fields terminated by '\t'
collection items terminated by ',';
数据:
1 english,80
2 math,89
3 chinese,95
导入数据:
load data local inpath '/ home/hadoop / structtable.txt' into table structtable;
查询语句:
Select * from structtable;
Select id from structtable;
Select course from structtable;
Select t.course.name from structtable t;
Select t.course.score from structtable t;

1.3.4.uniontype

参考资料:http://yugouai.iteye.com/blog/18491

2.视图

和关系型数据库一样,Hive 也提供了视图的功能,不过请注意,Hive 的视图和关系型数据库的数据还是有很大的区别:
1.只有逻辑视图,没有物化视图;
2.视图只能查询,不能 Load/Insert/Update/Delete 数据;
3.视图在创建时候,只是保存了一份元数据,当查询视图的时候,才开始执行视图对应的那些子查询
创建视图
create view view_name as select * from carss;
create view carss_view as select * from carss limit 500;
查看视图
show tables; // 可以查看表,也可以查看视图
desc view_name // 查看某个具体视图的信息
desc carss_view
删除视图
drop view view_name
drop view if exists carss_view
使用视图
create view sogou_view as select * from sogou_table where rank > 3 ;
select count(distinct uid) from sogou_view;

3.Hive函数

Hive高级操作_第1张图片

3.1.Hive内置函数

1.内容比较多,见《Hive官方文档》

https://cwiki.apache.org/confluence/display/Hive/LanguageManual+UDF

2.测试内置函数的快捷方式:

第一种方式:直接使用,例如:select concat('a','a') —> aa

第二种方式:

  • 创建一个 dual 表 create table dual(id string);
  • load 一个文件(一行,一个空格)到 dual 表
  • select substr('huangbo',2,3) from dual;

3.查看内置函数:
show functions;
显示函数的详细信息:
desc function abs;
显示函数的扩展信息:
desc function extended concat;

4.内置函数列表

关系运算

1. 等值比较: =
2. 等值比较:<=>
3. 不等值比较: <>和!=
4. 小于比较: <
5. 小于等于比较: <=
6. 大于比较: >
7. 大于等于比较: >=
8. 区间比较
9. 空值判断: IS NULL
10. 非空判断: IS NOT NULL
10. LIKE 比较: LIKE
11. JAVA 的 LIKE 操作: RLIKE
12. REGEXP 操作: REGEXP

数学运算

1. 加法操作: +
2. 减法操作: –
3. 乘法操作: *
4. 除法操作: /
5. 取余操作: %
6. 位与操作: &
7. 位或操作: |
8. 位异或操作: ^
9.位取反操作: ~

逻辑运算

1. 逻辑与操作: AND 、&&
2. 逻辑或操作: OR 、||
3. 逻辑非操作: NOT、!

复合类型构造函数

1. map 结构
2. struct 结构
3. named_struct 结构
4. array 结构
5. create_union

复合类型操作符

1. 获取 array 中的元素
2. 获取 map 中的元素
3. 获取 struct 中的元素

数值计算函数

1. 取整函数: round
2. 指定精度取整函数: round
3. 向下取整函数: floor
4. 向上取整函数: ceil
5. 向上取整函数: ceiling
6. 取随机数函数: rand
7. 自然指数函数: exp
8. 以 10 为底对数函数: log10
9. 以 2 为底对数函数: log2
10. 对数函数: log
11. 幂运算函数: pow
12. 幂运算函数: power
13. 开平方函数: sqrt
14. 二进制函数: bin
15. 十六进制函数: hex
16. 反转十六进制函数: unhex
17. 进制转换函数: conv
18. 绝对值函数: abs
19. 正取余函数: pmod
20. 正弦函数: sin
21. 反正弦函数: asin
22. 余弦函数: cos
23. 反余弦函数: acos
24. positive 函数: positive
25. negative 函数: negative

集合操作函数

1. map 类型大小:size
2. array 类型大小:size
3. 判断元素数组是否包含元素:array_contains
4. 获取 map 中所有 value 集合
5. 获取 map 中所有 key 集合
6. 数组排序

类型转换函数

1. 二进制转换:binary
2. 基础类型之间强制转换:cast

日期函数

1. UNIX 时间戳转日期函数: from_unixtime
2. 获取当前 UNIX 时间戳函数: unix_timestamp
3. 日期转 UNIX 时间戳函数: unix_timestamp
4. 指定格式日期转 UNIX 时间戳函数: unix_timestamp
5. 日期时间转日期函数: to_date
6. 日期转年函数: year
7. 日期转月函数: month
8. 日期转天函数: day
9. 日期转小时函数: hour
10. 日期转分钟函数: minute
11. 日期转秒函数: second
12. 日期转周函数: weekofyear
13. 日期比较函数: datediff
14. 日期增加函数: date_add
15. 日期减少函数: date_sub

条件函数

1. If 函数: if
2. 非空查找函数: COALESCE
3. 条件判断函数:CASE

字符串函数

1. 字符 ascii 码函数:ascii
2. base64 字符串
3. 字符串连接函数:concat
4. 带分隔符字符串连接函数:concat_ws
5. 数组转换成字符串的函数:concat_ws
6. 小数位格式化成字符串函数:format_number
7. 字符串截取函数:substr,substring
8. 字符串截取函数:substr,substring
9. 字符串查找函数:instr
10. 字符串长度函数:length
11. 字符串查找函数:locate
12. 字符串格式化函数:printf
13. 字符串转换成 map 函数:str_to_map
14. base64 解码函数:unbase64(string str)
15. 字符串转大写函数:upper,ucase
16. 字符串转小写函数:lower,lcase
17. 去空格函数:trim
18. 左边去空格函数:ltrim
19. 右边去空格函数:rtrim
20. 正则表达式替换函数:regexp_replace
21. 正则表达式解析函数:regexp_extract
22. URL 解析函数:parse_url
23. json 解析函数:get_json_object
24. 空格字符串函数:space
25. 重复字符串函数:repeat
26. 左补足函数:lpad
Stay hungry Stay foolish -- http://blog.csdn.net/zhongqi2513
27. 右补足函数:rpad
28. 分割字符串函数: split
29. 集合查找函数: find_in_set
30. 分词函数:sentences
31. 分词后统计一起出现频次最高的 TOP-K
32. 分词后统计与指定单词一起出现频次最高的 TOP-K

混合函数

1. 调用 Java 函数:java_method
2. 调用 Java 函数:reflect
3. 字符串的 hash 值:hash

XPathXML函数

1. xpath
2. xpath_string
3. xpath_boolean
4. xpath_short, xpath_int, xpath_long
5. xpath_float, xpath_double, xpath_number

汇总统计函数(UDAF)

1. 个数统计函数: count
2. 总和统计函数: sum
3. 平均值统计函数: avg
4. 最小值统计函数: min
5. 最大值统计函数: max
6. 非空集合总体变量函数: var_pop
7. 非空集合样本变量函数: var_samp
8. 总体标准偏离函数: stddev_pop
9. 样本标准偏离函数: stddev_samp
10.中位数函数: percentile
11. 中位数函数: percentile
12. 近似中位数函数: percentile_approx
13. 近似中位数函数: percentile_approx
14. 直方图: histogram_numeric
15. 集合去重数:collect_set
16. 集合不去重函数:collect_list

表格生成函数Table-Generating Functions(UDTF)

1.数组拆分成多行:explode(array)
2.Map 拆分成多行:explode(map)

3.2.Hive自定义函数UDF

当 Hive 提供的内置函数无法满足业务处理需要时,此时就可以考虑使用用户自定义函数
UDF(user-defined function)作用于单个数据行,产生一个数据行作为输出。(数学函数,字符串函数)
UDAF(用户定义聚集函数 User- Defined Aggregation Funcation):接收多个输入数据行,并产生一个输出数据行。(count,max)
UDTF(表格生成函数 User-Defined Table Functions):接收一行输入,输出多行(explode)

3.2.1.一个简单的UDF示例

1.先开发一个简单的 java 类,继承 org.apache.hadoop.hive.ql.exec.UDF,重载 evaluate 方法
Package com.ghgj.hive.udf
import java.util.HashMap;
import org.apache.hadoop.hive.ql.exec.UDF;
public class ToLowerCase extends UDF {
// 必须是 public,并且 evaluate 方法可以重载
public String evaluate(String field) {
String result = field.toLowerCase();
return result;
}
}
2.打成 jar 包上传到服务器
3.将 jar 包添加到 hive 的 classpath
hive>add JAR /home/hadoop/hivejar/udf.jar;
查看加入的 jar/jars 的命令:
hive> list jar;
4.创建临时函数与开发好的 class 关联起来
hive>create temporary function tolowercase as 'com.ghgj.hive.udf.ToLowerCase';
5.至此,便可以在 hql 在使用自定义的函数
select tolowercase(name),age from student;

3.2.2.Json数据解析UDF开发

现有原始 json 数据(rating.json)如下,
{"movie":"1193","rate":"5","timeStamp":"978300760","uid":"1"}
{"movie":"661","rate":"3","timeStamp":"978302109","uid":"1"}
{"movie":"914","rate":"3","timeStamp":"978301968","uid":"1"}
{"movie":"3408","rate":"4","timeStamp":"978300275","uid":"1"}
Stay hungry Stay foolish -- http://blog.csdn.net/zhongqi2513
{"movie":"2355","rate":"5","timeStamp":"978824291","uid":"1"}
{"movie":"1197","rate":"3","timeStamp":"978302268","uid":"1"}
{"movie":"1287","rate":"5","timeStamp":"978302039","uid":"1"}
{"movie":"2804","rate":"5","timeStamp":"978300719","uid":"1"}
{"movie":"594","rate":"4","timeStamp":"978302268","uid":"1"}
现在需要将数据导入到 hive 仓库中,并且最终要得到这么一个结果:

movie rate timeStamp uid
1193 5 978300760 1

该怎么做???(提示:可用内置 get_json_object 或者自定义函数完成)

3.2.3.Tranform实现

Hive 的 TRANSFORM 关键字提供了在 SQL 中调用自写脚本的功能。适合实现 Hive 中没有的功能又不想写 UDF 的情况。

具体以一个实例讲解。
Json 数据:{"movie":"1193","rate":"5","timeStamp":"978300760","uid":"1"}
需求:把 timestamp 的值转换成日期编号

1.先加载 rating.json 文件到 hive 的一个原始表 rate_json
create table rate_json(line string) row format delimited;
load data local inpath '/home/hadoop/rating.json' into table rate_json;

2.创建 rate 这张表用来存储解析 json 出来的字段:
create table rate(movie int, rate int, unixtime int, userid int) row format delimited fields terminated by '\t';
解析 json,得到结果之后存入 rate 表:
insert into table rate select 
get_json_object(line,'$.movie') as moive,
get_json_object(line,'$.rate') as rate,
get_json_object(line,'$.timeStamp') as unixtime,
get_json_object(line,'$.uid') as userid 
from rate_json;

3.使用 transform+python 的方式去转换 unixtime 为 weekday

先编辑一个 python 脚本文件

########python######代码
## vi weekday_mapper.py
#!/bin/python
import sys
import datetime
for line in sys.stdin:
 line = line.strip()
 movie,rate,unixtime,userid = line.split('\t')
 weekday = datetime.datetime.fromtimestamp(float(unixtime)).isoweekday()
 print '\t'.join([movie, rate, str(weekday),userid])

保存文件
然后,将文件加入 hive 的 classpath:
hive>add file /home/hadoop/weekday_mapper.py;
hive> insert into table lastjsontable select transform(movie,rate,unixtime,userid)
using 'python weekday_mapper.py' as(movie,rate,weekday,userid) from rate;

// 创建最后的用来存储调用 python 脚本解析出来的数据的表:lastjsontable
create table lastjsontable(movie int, rate int, weekday int, userid int) row format delimited fields terminated by '\t';

最后查询看数据是否正确:
select distinct(weekday) from lastjsontable;

4.Hive特殊分隔符处理

补充:hive 读取数据的机制:
1.首先用 InputFormat<默认是:org.apache.hadoop.mapred.TextInputFormat >的一个具体实现类读入文件数据,返回一条一条的记录(可以是行,或者是你逻辑中的“行”)。
2.然后利用 SerDe<默认:org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe>的一个具体实现类,对上面返回的一条一条的记录进行字段切割。

Hive 对文件中字段的分隔符默认情况下只支持单字节分隔符,如果数据文件中的分隔符是多字符的,如下所示:
01||huangbo
02||xuzheng
03||wangbaoqiang

4.1.使用RegexSerDe通过正则表达式来抽取字段

create table t_bi_reg(id string,name string)
row format serde 'org.apache.hadoop.hive.serde2.RegexSerDe'
with serdeproperties('input.regex'='(.*)\\|\\|(.*)','output.format.string'='%1$s %2$s')
stored as textfile;

hive>load data local inpath '/home/hadoop /hivedata/bi.dat' into table t_bi_reg;
hive>select * from t_bi_reg;

你可能感兴趣的:(Hive)