创建静态分区语法
CREATE TABLE IF NOT EXISTS t_student (
sno int,
sname string
) partitioned by(grade int)
row format delimited fields terminated by ',';
1,zhangsanfeng01,1
2,zhangsanfeng02,1
3,zhangsanfeng03,1
4,zhangsanfeng04,1
5,zhangsanfeng05,1
6,zhangsanfeng06,1
7,zhangsanfeng07,2
8,zhangsanfeng08,2
9,zhangsanfeng09,2
10,zhangsanfeng10,2
11,zhangsanfeng11,2
12,zhangsanfeng12,2
13,zhangsanfeng13,3
14,zhangsanfeng14,3
15,zhangsanfeng15,3
16,zhangsanfeng16,3
17,zhangsanfeng17,3
18,zhangsanfeng18,3
19,zhangsanfeng19,4
20,zhangsanfeng20,4
21,zhangsanfeng21,4
load data inpath '/yjx/student.txt' into table t_student partition(grade=1);
创建多分区表语法
CREATE TABLE IF NOT EXISTS t_teacher (
tno int,
tname string
) partitioned by(grade int,clazz int)
row format delimited fields terminated by ',';
注意:前后两个分区的关系为父子关系,也就是grade文件夹下面有多个clazz子文件夹。
1,jueyuan01,1,1
2,jueyuan02,1,1
3,jueyuan03,1,2
4,jueyuan04,1,2
5,jueyuan05,1,3
6,jueyuan06,1,3
7,jueyuan07,2,1
8,jueyuan08,2,1
9,jueyuan09,2,2
load data inpath '/yjx/teacher11.txt' into table t_teacher partition(grade=1,clazz=1);
查询数据
select * from t_student where grade = 1 ;
通过建立分区表,可以更加高效的查询出结果(因为已经分区过,相当于直接查找分区里的内容,而不是查询操作)
show partitions t_student;
alter table t_student add partition (day='99990102');
alter table t_student add partition (day='99990103') location '99990103';
alter table salgrade2 drop partition (day='99990102');
定义理解
开启动态分区的首先要在Hive会话中设置如下参数
set hive.exec.dynamic.partition=true;
set hive.exec.dynamic.partition.mode=nonstrict;
其余的参数详细配置如下
设置为true表示开启动态分区的功能(默认为false)
--hive.exec.dynamic.partition=true;
设置为nonstrict,表示允许所有分区都是动态的(默认为strict)
-- hive.exec.dynamic.partition.mode=nonstrict;
每个mapper或reducer可以创建的最大动态分区个数(默认为100)
比如:源数据中包含了一年的数据,即day字段有365个值,那么该参数就需要设置成大于365,如果使用默认
值100,则会报错
--hive.exec.max.dynamic.partition.pernode=100;
一个动态分区创建可以创建的最大动态分区个数(默认值1000)
--hive.exec.max.dynamic.partitions=1000;
全局可以创建的最大文件个数(默认值100000)
--hive.exec.max.created.files=100000;
当有空分区产生时,是否抛出异常(默认false)
-- hive.error.on.empty.partition=false;
案例1:动态插入学生年级班级信息
CREATE TABLE IF NOT EXISTS t_student_d (
sno int,
sname string
) partitioned by (grade int,clazz int)
row format delimited fields terminated by ',';
CREATE EXTERNAL TABLE IF NOT EXISTS t_student_e (
sno int,
sname string,
grade int,
clazz int
)
row format delimited fields terminated by ','
location "/yjx/student";
注意:如果静态分区的话,我们插入数据必须指定分区的值。如果想要插入多个班级的数据,我们要写很多的SQL并且执行很多次很麻烦,而且静态分区有可能会产生数据错误
静态分区导入数据
insert overwrite table t_student partition (grade=1) select * from t_student_e
where grade=1;
动态分区导入数据,动态分区会根据select的结果自动判断数据应该load到哪个分区
insert overwrite table t_student_d partition (grade,clazz) select * from
t_student_e ;
基本语法
load data [local] inpath 'datapath' [overwrite] into table student [partition (partcol1=val1,…)];
加载linux本地数据
切记必须和hiveserver2在同一个节点才可以上传否则会出现如下错误
SemanticException Line 1:23 Invalid path ‘’/root/d3.txt’': No files matching path file
load data local inpath ‘/root/user.txt’ into table t_user;
加载HDFS数据
加载并覆盖已有数据
通过查询插入数据
create table t_user1(
id int,
uname string
)
row format delimited fields terminated by ','
lines terminated by '\n';
create table t_user2(
id int,
pwd string
)
row format delimited fields terminated by ','
lines terminated by '\n';
-将查询结果插入一张表
insert overwrite table t_user1 select id,uname from t_user;
insert overwrite table t_user2 select id,pwd from t_user;
--将查询结果一次性存放到多张表
from t_user
insert overwrite table t_user1 select id,uname
insert overwrite table t_user2 select id,pwd;
将表中的数据备份
将查询结果存放到本地
按照指定的方式将数据输出到本地
先创建一个存放数据的目录
再导出查询结果的数据
insert overwrite local directory '/root/yjx/person'
ROW FORMAT DELIMITED fields terminated by ','
collection items terminated by '-'
map keys terminated by ':'
lines terminated by '\n'
select * from t_person;
将查询到的结果输出到HDFS
//创建存放数据的目录
hdfs dfs -mkdir -p /yjx/copy
//导出查询结果的数据
insert overwrite directory '/yjx/copy/user'
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
select * from t_user;
或者直接用HDFS命令保存表到对应的文件夹中
//创建存放数据的目录
hdfs dfs -mkdir -p /yjx/person
//使用HDFS命令拷贝文件到其他目录
hdfs dfs -cp /hive/warehouse/t_person/* /yjx/person
将表结构和数据同时备份
将数据导出到HDFS
//创建存放数据的目录
hdfs dfs -mkdir -p /yjx/copy
//导出查询结果的数据
export table t_person to '/yjx/copy';
删除表结构
drop table t_person;
恢复表结构和数据
import from '/yjx/copy';
需要注意的是:时间不同步,会导致导入导出失败
概念理解
分桶表出现的原因
数据分桶的原理
数据分桶的原理
方便抽样
提高join查询效率
获得更高的查询处理效率。桶为表加上了额外的结构,Hive在处理有些查询时能够利用这个结构。
具体而言,连接在两个(包含连接列)相同列上划分了桶的表,可以使用Map端连接(Map-side join)高效的实现
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uZxv4hij-1656257995434)(https://s2.loli.net/2022/06/26/PZ9H5YjfoSUtiNh.png)]
数据分桶实战
开启分桶功能
set hive.enforce.bucketing=true;
设置Reduce个数
我们需要确保reduce 的数量与表中的bucket 数量一致bucket个数会决定在该表或者该表的分区对应的hdfs目录下生成对应个数的文件,而mapreduce的个数是根据文件块的个数据确定的map个数。
set mapreduce.job.reduce=3;
创建表
CREATE TABLE t_citizen_bucket(
idcard int,
pname string,
province int
)clustered by(idcard) sorted by (pname desc) into 16 buckets
row format delimited fields terminated by ','
lines terminated by '\n';
create EXTERNAL table t_citizen(
idcard int,
pname string,
province int
)row format delimited fields terminated by ','
lines terminated by '\n'
location '/yjx/citizen';
数据导入(用idea得出来的数据)
for (int i = 1000; i < 10000; i++) {
System.out.println(i + "," + "admin" + (new Random().nextInt(89999) +
10000) + "," + i % 34);
}
将外部表的数据导入到分桶表
insert overwrite table t_citizen_bucket select * from t_citizen ;
定义与语法规范:
SELECT * FROM
具体语法理解:
定义语法理解:
语法:
SELECT * FROM
< N rows tosample>;
示例:
重点掌握
1、掌握Hive中开窗函数和自定义函数的应用
2、掌握Hive的行式存储和列式存储的区别理解内容
1、Hive的同比与环比练习 -40
2、Hive的优化 -41~42
3、Hive的配置参数 -44
4、Hive的数据倾斜 -45
理解:
order by会对输入做全局排序,因此只有一个reducer,会导致当输入规模较大时,需要较长的计算时间
排序语法
select * from t_student_d order by sno;
select grade,count(sno) cs from t_student_d group by grade order by cs;
select grade,count(sno) cs from t_student_d group by grade order by cs,grade;
理解:
设置reduce的个数
set mapreduce.job.reduce=3;
查看reduce的个数
set mapreduce.job.reduce;
排序
select * from t_student_d sort by sname;
将查询结果导入到文件中
insert overwrite local directory '/root/student' select * from t_student_d sort by clazz asc, grade desc;
理解
设置reduce个数
set mapreduce.job.reduce=7;
排序
insert overwrite local directory '/data/student' select * from t_student_d distribute by sname;
理解
select * from t_student_d sort cluster by sname;
select * from t_student_d distribute by sname sort by sname;
内置函数
内置函数分类
UDTF函数
create table t_movie1(
id int,
name string,
types string
)
row format delimited fields terminated by ','
lines terminated by '\n';
1,这个杀手不太冷,剧情-动作-犯罪
2,七武士,动作-冒险-剧情
3,勇敢的心,动作-传记-剧情-历史-战争
4,东邪西毒,剧情-动作-爱情-武侠-古装
5,霍比特人,动作-奇幻-冒险
load data inpath '/yjx/movie1.txt' into table t_movie1;
select explode(split(types,"-")) from t_movie1;
select id,name,type from t_movie1,lateral view explode(split(types,"-"))typetable as type;
create table t_movie2(
id int,
name string,
type string
)
row format delimited fields terminated by ','
lines terminated by '\n';
1,这个杀手不太冷,剧情
1,这个杀手不太冷,动作
1,这个杀手不太冷,犯罪
2,七武士,动作
2,七武士,冒险
2,七武士,剧情
3,勇敢的心,动作
3,勇敢的心,传记
3,勇敢的心,剧情
3,勇敢的心,历史
3,勇敢的心,战争
4,东邪西毒,剧情
4,东邪西毒,动作
4,东邪西毒,爱情
4,东邪西毒,武侠
4,东邪西毒,古装
5,霍比特人,动作
5,霍比特人,奇幻
5,霍比特人,冒险
load data inpath '/yjx/movie2.txt' into table t_movie2;
select id,concat_ws(':',collect_set(type)) as types from t_movie2 group by id;
窗口函数理解
语法:
窗口函数的分类
测试数据
-- 创建表
create table t_fraction(
name string,
subject string,
score int)
row format delimited fields terminated by ","
lines terminated by '\n';
-- 测试数据 fraction.txt
孙悟空,语文,10
孙悟空,数学,73
孙悟空,英语,15
猪八戒,语文,10
猪八戒,数学,73
猪八戒,英语,11
沙悟净,语文,22
沙悟净,数学,70
沙悟净,英语,31
唐玄奘,语文,21
唐玄奘,数学,81
唐玄奘,英语,23
-- 上传数据
load data inpath '/yjx/fraction.txt' into table t_fraction;
sum(求和)min(最小)max(最大)avg(平均值)count(计数)
+-------+----------+--------+----------+
| name | subject | score | sumover |
+-------+----------+--------+----------+
| 唐玄奘 | 英语 | 23 | 321 |
| 唐玄奘 | 数学 | 81 | 321 |
| 唐玄奘 | 语文 | 21 | 321 |
| 沙悟净 | 英语 | 31 | 321 |
| 沙悟净 | 数学 | 12 | 321 |
| 沙悟净 | 语文 | 22 | 321 |
| 猪八戒 | 英语 | 11 | 321 |
| 猪八戒 | 数学 | 73 | 321 |
| 猪八戒 | 语文 | 10 | 321 |
| 孙悟空 | 英语 | 15 | 321 |
| 孙悟空 | 数学 | 12 | 321 |
| 孙悟空 | 语文 | 10 | 321 |
+-------+----------+--------+----------+
+-------+----------+--------+----------+
| name | subject | score | sumover |
+-------+----------+--------+----------+
| 唐玄奘 | 数学 | 81 | 185 |
| 沙悟净 | 数学 | 19 | 185 |
| 猪八戒 | 数学 | 73 | 185 |
| 孙悟空 | 数学 | 12 | 185 |
| 唐玄奘 | 英语 | 23 | 80 |
| 沙悟净 | 英语 | 31 | 80 |
| 猪八戒 | 英语 | 11 | 80 |
| 孙悟空 | 英语 | 15 | 80 |
| 唐玄奘 | 语文 | 21 | 94 |
| 沙悟净 | 语文 | 22 | 94 |
| 猪八戒 | 语文 | 41 | 94 |
| 孙悟空 | 语文 | 10 | 94 |
+-------+----------+--------+----------+
语法顺序
rows必须跟在order by字句之后,对排序的结果进行排序,使用固定的行数来限制分区中的数据行数量
常见排序窗口函数及区别
测试排序
select name,subject,score,rank() over(partition by subject order by score desc) rp,
dense_rank() over(partition by subject order by score desc) drp,
row_number() over(partition by subject order by score desc) rnp
from t_fraction;
+-------+----------+--------+-----+------+------+
| name | subject | score | rp | drp | rnp |
+-------+----------+--------+-----+------+------+
| 唐玄奘 | 数学 | 81 | 1 | 1 | 1 |
| 猪八戒 | 数学 | 73 | 2 | 2 | 2 |
| 孙悟空 | 数学 | 73 | 2 | 2 | 3 |
| 沙悟净 | 数学 | 70 | 4 | 3 | 4 |
| 沙悟净 | 英语 | 31 | 1 | 1 | 1 |
| 唐玄奘 | 英语 | 23 | 2 | 2 | 2 |
| 孙悟空 | 英语 | 15 | 3 | 3 | 3 |
| 猪八戒 | 英语 | 11 | 4 | 4 | 4 |
| 沙悟净 | 语文 | 22 | 1 | 1 | 1 |
| 唐玄奘 | 语文 | 21 | 2 | 2 | 2 |
| 猪八戒 | 语文 | 10 | 3 | 3 | 3 |
| 孙悟空 | 语文 | 10 | 3 | 3 | 4 |
+-------+----------+--------+-----+------+------+
percent_rank() 计算给定行的百分比排名,可以用来计算超过了百分之多少的人
select name,subject,score,
row_number() over(partition by subject order by score) as row_number,
percent_rank() over(partition by subject order by score) as percent_rank
from t_fraction;
+-------+----------+--------+-------------+---------------------+
| name | subject | score | row_number | percent_rank |
+-------+----------+--------+-------------+---------------------+
| 沙悟净 | 数学 | 70 | 1 | 0.0 |
| 猪八戒 | 数学 | 73 | 2 | 0.3333333333333333 |
| 孙悟空 | 数学 | 73 | 3 | 0.3333333333333333 |
| 唐玄奘 | 数学 | 81 | 4 | 1.0 |
| 猪八戒 | 英语 | 11 | 1 | 0.0 |
| 孙悟空 | 英语 | 15 | 2 | 0.3333333333333333 |
| 唐玄奘 | 英语 | 23 | 3 | 0.6666666666666666 |
| 沙悟净 | 英语 | 31 | 4 | 1.0 |
| 猪八戒 | 语文 | 10 | 1 | 0.0 |
| 孙悟空 | 语文 | 10 | 2 | 0.0 |
| 唐玄奘 | 语文 | 21 | 3 | 0.6666666666666666 |
| 沙悟净 | 语文 | 22 | 4 | 1.0 |
+-------+----------+--------+-------------+---------------------+
Hive当中的参数、变量都是以命名空间开头的
命名空间 | 读写权限 | 含义 |
---|---|---|
hiveconf | 可读写 | hive_site当中的各配置变量 |
system | 可读写 | 系统变量,包含JVM运行参数等,例如:system:user.name=root |
env | 只读 | 环境变量,例如:env:JAVA_HOME |
hivevar | 可读写 | sql中直接使用的变量,例如:hive -d val=key |
通过 $ {}方式进行引用,其中system、env下的变量必须以前缀开头
配置文件方式
默认配置文件:hive-default.xml
用户自定义配置文件: ${HIVE_HOME}/conf/hive-site.xml
注意:用户自定义配置会覆盖默认配置。另外,Hive也会读入Hadoop的配置,因为Hive是作为
Hadoop的客户端启动的,Hive的配置会覆盖Hadoop的配置。配置文件的设定对本机启动的所有Hive进程都有效。
命令行参数方式
启动Hive时,可以在命令行添加-hiveconf param=value来设定参数。
例如:
beeline -u jdbc:hive2://yjx103:10000 -n root -hiveconf mapred.reduce.tasks=10;
从本质来说,导致数据倾斜有两种原因:
任务读取大文件,最常见的就是读取压缩的不可分割的大文件
任务需要处理大量相同键的数据
数据含有大量无意义的数据,例如空值,字符串等
含有倾斜数据在进行聚合计算时无法聚合中间结果,大量数据都需要经过Shuffle阶段的处理,引起数据倾斜
数据在计算时做多维数据集合,导致维度膨胀引起的数据倾斜
两个表进行join时,都含有大量相同的倾斜数据键
行式存储
列式存储
图解:
insert into t_stored_orc select * from t_stored_text;
TextFile
SequenceFile
RCFile
定义理解:
特点
ORCFile
定义理解:
相比RCFile的优点
Block-Compressed SequenceFile格式
参考资料:Hive 文件存储格式 - hyunbar - 博客园 (cnblogs.com)
Hive数据存储格式详细讲解(好文点赞收藏!)_KG大数据的博客-CSDN博客_数据存储格式
TextFile
create table t_stored_text (
c1 string,
c2 string,
c3 string,
c4 string,
c5 string,
c6 string,
c7 string
)ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
STORED AS TEXTFILE ;
load data inpath '/yjx/test.data' into table t_stored_text ;
ORCFile
create table t_stored_orc (
c1 string,
c2 string,
c3 string,
c4 string,
c5 string,
c6 string,
c7 string
)ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
STORED AS ORC ;
insert into t_stored_orc select * from t_stored_text;