Hive详解
-
- 一、数据类型
-
- 二、运算部分
-
- 1. 数据类型转换
-
- 2. 关系运算符
- 3. 算术运算符
- 4. 逻辑运算符
- 5. 集合运算
- 6. 复杂的运算符
- 三、常用shell命令
- 四、常见配置文件及参数设置
-
- 五、DQL
-
- 1. 通用模板
-
- 2. 运行顺序
- 3. 经典查询
- 4. 连接查询
- 六、DDL
-
- 1. 对database操作
-
- 1) 创建数据库
- 2) 查询数据库
- 3) 修改数据库
- 4) 删除数据库
- 2. 对table操作
-
- 1) 创建表
-
- 1° 基本语法
- 2° 常用语句
- 3° 内部表和外部表
- 2) 查询表
- 3) 修改表
- 4) 修改表分区
-
- 1° 分区类别
- 2° 查看分区
- 3° 添加分区
- 4° 分区名称修改
- 5° 修改分区路径
- 6° 删除分区
- 5) 删除表
- 七、DML
-
- 1. hive中常用的存储格式
- 2. load
- 3. import/export(导入/导出)
- 4. insert
- 5. udpate/delete
- 八、函数
-
- (一)、内置函数
-
- 1. 数字函数
- 2. 日期函数
- 3. 字符函数
- 4. 条件函数
- 5. 聚合函数
- 6. 窗口函数
-
- a. 聚合类窗口函数
- b. 排序类窗口函数
- c. 位移类窗口函数
- d. 分布类窗口函数
- e. 头尾窗口函数
- 7. 表生成函数explode(行转列)
- 8. reflect函数
- (二)、自定义函数
-
- 第一步:继承和重写
- 第二步:打包加载
- 第三步:创建函数
- 第四步:使用自定义函数
- 九、SQL优化
-
Hive 是基于Hadoop的 一个数据仓库工具,将结构化的数据文件映射为一张表,并提供了sql的curd的功能。
同时,hive的本质是将HQL转换为MapReduce程序,在hadoop中进行伪数据库的操作。(数据存储在HDFS/计算在MapReduce/执行在Yarn)
一、数据类型
1. 基本数据类型
* 整型
>> - tinyint
>> - smallint
>> - int
>> - bigint
>>
* 布尔型
>> - boolean
>>
* 浮点型
>> - float
>> - double
>> - deicimal
>
> timestamp
> date
> string
> varchar
> char
> binary (字节数组)
2. 集合数据类型
eg: array<string>
eg: map<string, int>
eg: struct<street:string, city:string>
eg: uniontype<int,double,array<string>,struct<a:int,b:string>>
二、运算部分
1. 数据类型转换
1° 隐式转换
任何整数类型都可以隐式地转化为一个范围更广的类型
所有整数类型/float/string类型都可以隐式转换为double
tinyint/smallint/int都可以转化为float
boolean类型不可以转换为其他任何类型
2° 手动操作
cast(value as type)
使用cast操作进行数据类型转换,如果强制转换失败,表达式返回null。
该过程的内部操作是通过round()或者floor()函数来实现的,而不是cast
cast(date as date)
cast(timestamp as date)
cast(string as date)
cast(date as timestamp)
cast(date as string)
select (cast(cast(col as string) as double)) from tablename;
2. 关系运算符
=
<>
< <=
> >=
is (not) null
(not) A like B
rlike
regexp
3. 算术运算符
+
-
*
/
%
&
|
^
~
4. 逻辑运算符
A and B
&&
or
||
not
!
5. 集合运算
union
union all
set hive.mapred.mode=nonstrict;
set hive.strict.checks.cartesian.product = false;
select *
from hive_4_product_1
where product_id not in (select product_id from hive_4_product_2);
SELECT *
FROM hive_4_product_1
WHERE product_id NOT IN (SELECT product_id FROM hive_4_product_2)
UNION
SELECT *
FROM hive_4_product_2
WHERE product_id NOT IN (SELECT product_id FROM hive_4_product_1)
SELECT *
FROM hive_4_product_1
WHERE product_id IN (SELECT product_id FROM hive_4_product_2)
6. 复杂的运算符
运算符 |
操作 |
描述 |
A[n] |
A是一个数组,n是一个int |
它返回数组A的第n个元素,第一个元素的索引0。 |
M[key] |
M 是一个 Map 并 key 的类型为K |
它返回对应于映射中关键字的值。 |
S.x |
S 是一个结构 |
它返回S的s字段 |
三、常用shell命令
$ bin/hive
$ hive
show database;
use default;
quit;
exit;
show tables;
desc tablename;
$ hive -e "select * from tablename";
$ hive -f ./hive.sql
$ hive -f ./hive.sql > ./hive_data.txt
hive> dfs -ls /;
set;
hive -help
cat .hivehistory
四、常见配置文件及参数设置
1. 常见配置文件
hive-default.xml
hive-site.xml
2. 常见参数设置
set;
set -v;
set key = value;
set mapred.reduce.tasks
mapred.map.tasks
set hive.exec.dynamic.partition=true;
set hive.exec.dynamic.partition.mode=nonstrict;
set hive.exec.parallel=true;
set hive.exec.parallel.thread.number=16;
set hive.support.quoted.identifiers=None;
set hive.mapred.mode=strict;
set hive.execution.engine=tez;
set tez.grouping.min-size=556000000;
set tez.grouping.max-size=3221225472;
set tez.queue.name=HIGH_BIE_DYNAMIC;
set hive.map.aggr=true;
set auto.convert.join=true;
...
...
五、DQL
1. 通用模板
select [all | distinct] select_expr, select_expr, ...
from table_reference
[where where_condition]
[group by col_list]
[having col_list]
[window ]
[order by col_list]
[cluster by col_list | [distribute by col_list] [sort by col_list]]
[limit [offset,] rows];
1) 排序部分详解
order by
sort by
distribute by
cluster by
eg:
select * from emp distribute by deptno sort by deptno;
select * from emp cluster by deptno;
order by
sort by
distribute by
cluster by
2. 运行顺序
from
join
where
group by
having
select
distinct
order by | cluster by | (distribute by/sort by)
limit
3. 经典查询
set hive.support.quoted.identifiers=None;
select `(rank|inc_day)?+.+`
from tmp_dm_icsm.tmp_cost_task_dim_tableau_wild_oylz
limit 10;
4. 连接查询
join
left outer join
right outer join
full outer join
left semi join
select user.id,user.name from user
left semi join post
on (user.id=post.uid);
select id,name from user
where id in
(select uid from post);
六、DDL
数据定义语言:常用的有CREATE和DROP,用于在数据库中创建新表或删除表,以及为表加入索引等
1. 对database操作
1) 创建数据库
create database db_name;
create database if not exists db_name;
create database if not exists db_name comment 'this is test db';
create database db_name location '/hive/db/db_name';
create database db_name with dbproperties('name'='dachun','date'='20200202');
2) 查询数据库
show databases;
show databases like 'db_hive*';
desc database db_hive;
desc database extended db_hive;
use db_hive;
show create database db_hive;
describe database db_test;
3) 修改数据库
alter database <database_name> set dbproperties (''='',..);
alter database db_hive set dbproperties ('owner'='senfos.w','date'='2022-11-6');
alter database db_hive set location '/hive/db/db_hive';
4) 删除数据库
drop (database|schema) [if exists] database_name [restrict|cascade];
2. 对table操作
1) 创建表
1° 基本语法
CREATE [EXTERNAL] TABLE [IF NOT EXISTS] table_name
[(col_name data_type [COMMENT col_comment], ...)]
[COMMENT table_comment]
[PARTITIONED BY (col_name data_type [COMMENT col_comment], ...)]
[CLUSTERED BY (col_name, col_name, ...)
[SORTED BY (col_name [ASC|DESC], ...)] INTO num_buckets BUCKETS]
[ROW FORMAT row_format]
[STORED AS file_format]
[LOCATION hdfs_path]
[TBLPROPERTIES (property_name=property_value, ...)]
[AS select_statement]
用户可以用 IF NOT EXISTS 选项来忽略这个异常。
际数据的路径(LOCATION),在删除表的时候,内部表的元数据和数据会被一起删除,而外
部表只删除元数据,不删除数据。
DELIMITED [FIELDS TERMINATED BY char] [COLLECTION ITEMS TERMINATED BY char]
[MAP KEYS TERMINATED BY char] [LINES TERMINATED BY char]
| SERDE serde_name [WITH SERDEPROPERTIES (property_name=property_value,
property_name=property_value, ...)]
用户在建表的时候可以自定义 SerDe 或者使用自带的 SerDe。如果没有指定 ROW
FORMAT 或者 ROW FORMAT DELIMITED,将会使用自带的 SerDe。在建表的时候,用户还需
要为表指定列,用户在指定表的列的同时也会指定自定义的 SerDe,Hive 通过 SerDe 确定表
的具体的列的数据。
SerDe 是 Serialize/Deserilize 的简称, hive 使用 Serde 进行行对象的序列与反序列化。
常用的存储文件类型:SEQUENCEFILE(二进制序列文件)、TEXTFILE(文本)、RCFILE(列
式存储格式文件)
如果文件数据是纯文本,可以使用STORED AS TEXTFILE。如果数据需要压缩,使用 STORED
AS SEQUENCEFILE。
2° 常用语句
create table if not exists student(
id int,
name string
)
row format delimited fields terminated by '\t'
stored as textfile
location '/user/hive/warehouse/student';
create table if not exists student2 as select id, name from student;
create table if not exists student3 like student;
3° 内部表和外部表
external修饰的是内部表(managed table),被external修饰的为外部表.
内部表数据由Hive自身管理,外部表数据由HDFS管理
内部表数据存储的位置是hive.metastore.warehouse.dir(默认:/user/hive/warehouse),外部表数据的存储位置由自己制定(如果没有LOCATION,Hive将在HDFS上的/user/hive/warehouse文件夹下以外部表的表名创建一个文件夹,并将属于这个表的数据存放在这里)
删除内部表会直接删除元数据(metadata)及存储数据;删除外部表仅仅会删除元数据,HDFS上的文件并不会被删除
对内部表的修改会将修改直接同步给元数据,而对外部表的表结构和分区进行修改,则需要修复(MSCK REPAIR TABLE table_name;)
每天将收集到的网站日志定期流入 HDFS 文本文件。在外部表(原始日志表)的基础上做大量的统计分析,用到的中间表、结果表使用内部表存储,数据通过 SELECT+INSERT 进入内部表。
alter table student2 set tblproperties('EXTERNAL'='TRUE');
alter table student2 set tblproperties('EXTERNAL'='FALSE');
desc formatted student2;
2) 查询表
desc formatted student2;
show tables;
desc table_name;
show partitions table_name;
select table_coulm
from table_name
where partition_name = '2014-02-25';
dfs -ls /user/hive/warehouse/table02;
3) 修改表
alter table table_name rename to new_table_name;
ALTER TABLE table_name CHANGE
[CLOUMN] col_old_name col_new_name column_type
[CONMMENT col_conmment]
[FIRST|AFTER column_name];
ALTER TABLE test_table CHANGE col1 col2 STRING COMMENT 'The datatype of col2 is STRING' AFTER col3;
hive> ALTER TABLE employee CHANGE name ename String;
hive> ALTER TABLE employee CHANGE salary salary Double;
ALTER TABLE table_name ADD|REPLACE COLUMNS (col_name data_type [CONMMENT col_comment], ...);
ALTER TABLE employee ADD COLUMNS (dept STRING COMMENT 'Department name');
ALTER TABLE employee REPLACE COLUMNS ( eid INT empid Int, ename STRING name String);
ALTER TABLE table_name SET TBLPEOPERTIES table_properties;
ALTER TABLE table_name SET SERDE serde_class_name
[WHIT SERDEPROPERTIES serde_properties];
ALTER TABLE table_name SET SERDEPROPERTIES serde_properties;
ALTER TABLE table_name SET FILEFORMAT file_format;
ALTER TABLE table_name CLUSTERED BY (col_name, col_name, ...)
[SORTED By (col_name, ...)] INTO num_buckets BUCKETS;
4) 修改表分区
1° 分区类别
set hive.exec.dynamic.partition=true
set hive.exec.dynamic.partition.mode=strict/nonstrict
set hive.exec.max.dynamic.partitions=1000
set hive.exec.max.dynamic.partitions.pernode=100
2° 查看分区
show partitions 表名;
3° 添加分区
alter table part1 add partition(dt='2019-09-10');
alter table part1 add partition(dt='2019-09-13') partition(dt='2019-09-12');
alter table part1 add partition(dt='2019-09-11') location '/user/hive/warehouse/qf1704.db/part1/dt=2019-09-10';
4° 分区名称修改
alter table part1 partition(dt='2019-09-10') rename to partition(dt='2019-09-14');
5° 修改分区路径
alter table part1 partition(dt='2019-09-14') set location 'hdfs://hadoo01:9000/user/hive/warehouse/qf24.db/part1/dt=2019-09-09';
6° 删除分区
alter table part1 drop partition(dt='2019-09-14');
alter table part1 drop partition(dt='2019-09-12'),partition(dt='2019-09-13');
5) 删除表
drop table emp;
七、DML
1. hive中常用的存储格式
textFile、ORCFile、Parquet
textFile : hive默认的存储格式 ,默认为行存储
ORCFile :ORC数据压缩率比较高,通过采用数据按照行分块,每个块按照列存储,其中每个存储都一个索引
Parquet :Parquet具有很好的压缩性能,可以减少大量的表扫描和反序列化的时间
创建表时通过stored as 关键字指定表的存储格式,默认为textFile
通过对比这三种磁盘占用:orc<parquet<textfile
通过对比这三种格式查询时间:orc<parquet<textfile
2. load
load data [local] inpath '数据的 path' [overwrite] into table
student [partition (partcol1=val1,…)];
load data local inpath
'/opt/module/hive/datas/student.txt' into table default.student;
load data inpath '/user/atguigu/hive/student.txt'
overwrite into table default.student;
3. import/export(导入/导出)
import table student2 from '/user/hive/warehouse/export/student';
export table default.student to '/user/hive/warehouse/export/student';
4. insert
insert into table student_par values(1,'wangwu'),(2,'zhaoliu');
insert overwrite table student_par select id, name from student where month='201709';
from student
insert overwrite table student partition(month='201707')
select id, name where month='201709'
insert overwrite table student partition(month='201706')
select id, name where month='201709';
5. udpate/delete
1. update性能太差,且使用时对表结构有特殊要求,基本不使用
2. delete不存在,删除部分数据需通过alter+drop删除部分表表空间的内容
八、函数
(一)、内置函数
show functions;
desc function upper;
desc function extended upper;
1. 数字函数
abs
conv(BIGINT num, int from_base, int to_base)
round(double a[, int d])
floor(double a)
ceil(double a)
rand(),rand(int seed)
exp(double a)
log(double base, double a)
pow(double a, double p)
power(double a, double p)
sqrt(double a)
2. 日期函数
from_unixtime(bigint unixtime[, string format])
unix_timestamp()
unix_timestamp(string date)
unix_timestamp(string date, string pattern)
to_date(string timestamp[, string pattern])
year/month/day/hour/minute/second/weekofyear<返回日期在当前的周数>(string date)
datediff(string enddate, string startdate)
date_add(string startdate, int days)
date_sub (string startdate, int days)
3. 字符函数
length()
reverse()
concat(string A, string B…)
concat_ws(string SEP, string A, string B…)
substr(string A, int start[, int len])/substring(string A, int start[, int len])
upper()/ucase()
lower()/lcase()
trim()
ltrim()
rtrim()
lpad(string str, int len, string pad)/rpad()
split(string str, string pat)
regexp_replace()
regexp_extract()
4. 条件函数
if(boolean testCondition, T valueTrue, T valueFalseOrNull)
select COALESCE(null,'100','50') from tableName;
case a when b then c [when d then e]* [else f] end
case when a then b [when c then d]* [else e] end
5. 聚合函数
count(distinct/all)
sum()
avg()
min()
max()
6. 窗口函数
<窗口函数> over ([partition by <分组字段>] order by <排序字段> [rows between 开始位置 and 结束位置])
a. 聚合类窗口函数
count() over()
sum() over()
avg() over()
min() over()
max() over()
eg:
select
deptno,
sum(sal) over (partition by deptno order by sal desc) my_window_name as sum_sal,
max(sal) over (partition by deptno order by sal desc) my_window_name as max_sal,
min(sal) over (partition by deptno order by sal desc) my_window_name as min_sal,
avg(sal) over (partition by deptno order by sal desc) my_window_name as avg_sal
from scott.emp
window my_window_name as (partition by deptno order by sal desc)
b. 排序类窗口函数
row_number()over()
rank()over()
dense_rank()over()
c. 位移类窗口函数
lag( exp_str,offset,defval) over(partition by .. order by …)
lead(exp_str,offset,defval) over(partition by .. order by …)
- exp_str 是字段名
- Offset 是偏移量,即是上1个或上N个的值,假设当前行在表中排在第5行,offset 为3,则表示我们所要找的数据行就是表中的第2行(即5-3=2)。
- Defval 默认值,当两个函数取 上N 或者 下N 个值,当在表中从当前行位置向前数N行已经超出了表的范围时,lag() 函数将defval这个参数值作为函数的返回值,若没有指定默认值,则返回NULL,那么在数学运算中,总要给一个默认值才不会出错。
d. 分布类窗口函数
percent_rank() over()
cume_dist() over()
SELECT
uid,
score,
rank() OVER my_window_name AS rank_num,
PERCENT_RANK() OVER my_window_name AS prk
FROM exam_record
WINDOW my_window_name AS (ORDER BY score desc)
e. 头尾窗口函数
first_value() over()
last_value() over()
eg:
select distinct deptno,
first_value(sal) over(partition by deptno order by sal desc) as max_sal
from scott.emp;
7. 表生成函数explode(行转列)
explode(col)
lateral view
select class,student_name
from default.classinfo
lateral view explode(split(student,',')) t as student_name;
8. reflect函数
select reflect("org.apache.commons.lang.math.NumberUtils","isNumber","123");
(二)、自定义函数
UDF: 一进一出
UDAF: 多进一出
UDTF: 一进多出
第一步:继承和重写
org.apache.hadoop.hive.ql.UDF
org.apache.hadoop.hive.ql.exec.UDAF
org.apache.hadoop.hive.ql.exec.UDAFEvaluator
org.apache.hadoop.hive.ql.udf.generic.GenericUDF
evaluate()
Evaluator 需要实现 init、iterate、terminatePartial、merge、terminate 这几个函数
initlizer()
getdisplay()
evaluate()
第二步:打包加载
add jar /hivedata/udf.jar;
第三步:创建函数
create temporary function fun_demo as 'com.qf.hive.fun_demo';
show functions ;
第四步:使用自定义函数
select maxInt(mgr) from emp;
九、SQL优化
explain select deptno, avg(sal) avg_sal from emp group by
deptno;
1. 常见优化策略
1. map端连接
2. 合理设置maptask
3. 合理设置reducetask
4. 小文件合并
5. 学会使用分区/分桶
6. 注意负载均衡,避免数据倾斜(尽量避免使用count(distinct))
7. 注意join/group by的使用
8. 通过查看执行计划分析优化方案
...
...
2. 优化实现
1) map端连接
SELECT a.key, a.value
FROM a JOIN b
ON a.key = b.key;