Hive万字总结
Posted Mr.zhou_Zxy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hive万字总结相关的知识,希望对你有一定的参考价值。
目录
1 Hive基本概念
1.1 什么是Hive
- Hive简介
Hive:由FaceBook开源用于解决海量结构化日志的数据统计工具
Hive:基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张表,并提供类SQL的查询功能。
- Hive本质
将HSQL转化成MapReduce程序
Hive处理的数据存储在HDFS
Hive分析数据底层实现的是MR
执行程序运行在Yarn上
1.2 Hive的优缺点
1.2.1 优点
接口采用类SQL语法,提供快速开发的能力
避免了去写MR程序,减少开发人员的学习成本
Hive的执行延迟比较高,因此Hive常用于数据分析,对实时性要求不高的场合
Hive的优势在于处理大数据,对于处理小数据没有优势,因为Hive的执行延迟比较高
Hive支持自定义函数,用户可以根据自己的需求来实现自己的函数
1.2.2 缺点
Hive的HSQL表达能力有限
迭代算法无法表达
数据挖掘方面不擅长,由于MR数据处理流程的限制,效率更高的算法却无法实现
Hive的效率 比较低
Hive自动生成的MR作业,通常情况下不够智能化
Hive调优比较困难,粒度较粗
1.3 Hive运行机制
Hive通过用户提供的一系列交互接口,接收到用户的指令(SQL),使用自己的Driver,结合元数据(Metastore),将这些指令翻译
成MR,提交到Hadoop中执行,最后,将执行返回的结果输出到用户交互接口。
1.4 Hive和数据库比较
由于Hive采用类似SQL的查询语言HQL,因此很容易将Hive理解为数据库。其实从结构来看,Hive 和数据库除了用于类似的查询语言,
再无类似之处。
1.4.1 数据更新
由于Hive是针对数据仓库应用设计的,而数据仓库的内容是读多写少。因此,Hive中不建议对数据的改写,所有数据都是在加载的时候
确定好的。而数据库中的数据通常是需要进行修改的,因此可以采用insert into ... values添加数据,使用update ... set修改数据
1.4.2 执行延迟
Hive在查询数据的时候,由于没有索引,需要扫描整个表。因此延迟较高。由于Hive底层使用的MR框架,而MR本身具有较高的延迟,因此
在利用MR执行Hive查询的时候,也有较高的延迟。
1.4.3 数据规模
由于Hive简历在集群上可以利用MR进行并行计算,因此可以支持很大规模的数据。对应的,数据库可以支持的数据规模较小。
2 Hive安装
2.1 安装JDK
2.2 安装Hadoop
2.3 安装mysql
2.4 安装Hive
2.4.1 安装
##1. 解压
##2. 改名
[root@hadoop apps]# mv apache-hive-1.2.1-bin/ hive-1.2.1
##3. 配置环境变量
[root@hadoop hive-1.2.1]# vi /etc/profile
## 自定义环境变量
export JAVA_HOME=/opt/apps/jdk1.8.0_45
export HADOOP_HOME=/opt/apps/hadoop-2.8.1
export HIVE_HOME=/opt/apps/hive-1.2.1
export PATH=$PATH:$JAVA_HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$HIVE_HOME/bin
export CLASS_PATH=.:$JAVA_HOME/lib
##4. 启动命令行
[root@hadoop bin]# start-dfs.sh
[root@hadoop bin]# start-yarn.sh
2.4.2 hive远程模式
- hive-site.xml
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<configuration>
<property>
<name>javax.jdo.option.ConnectionURL</name>
<value>jdbc:mysql://hadoop:3306/hive?createDataBaseIfNotExists=true</value>
</property>
<property>
<name>javax.jdo.option.ConnectionDriverName</name>
<value>com.mysql.jdbc.Driver</value>
</property>
<property>
<name>javax.jdo.option.ConnectionUserName</name>
<value>root</value>
</property>
<property>
<name>javax.jdo.option.ConnectionPassword</name>
<value>111213</value>
</property>
</configuration>
- 上传mysql的jdbc驱动jar包到hive的lib下
- 分配权限
mysql> grant all privileges on . to ‘root’@’%’ identified by ‘123456’ with grant option;
mysql> flush privileges;
mysql> grant all privileges on . to ‘root’@‘hadoop’ identified by ‘123456’ with grant option;
mysql> flush privileges;
- Navicat新建数据库hive
字符集:latin1
2.4.3 Thrift server
hive --service hiveserver2 &
beeline
!connect jdbc:hive2://hadoop:10000
2.5 Hive日志
Hive日志默认在tmp下,修改日志的路径
[root@hadoop conf]# mv hive-log4j.properties.template hive-log4j.properties
[root@hadoop conf]# vi hive-log4j.properties
hive.log.dir=/opt/apps/hive-1.2.1/logs
3 Hive数据类型
3.1 基本数据类型
Hive数据类型 | Java数据类型 | 长度 |
---|---|---|
TINYINT | byte | 1byte |
SMALLINT | short | 2byte |
INT | int | 4byte |
BIGINT | long | 8byte |
BOOLEAN | boolean | 布尔类型 |
FLOAT | float | 单精度浮点型 |
DOUBLE | double | 双精度浮点型 |
STRING | string | 字符系列 |
TIMESTAMP | 时间类型 | |
BINART | 字节数组 |
Hive的String类型相当于数据库的Varchar类型,是一个不可变的字符串
3.2 集合数据类型
数据类型 | 描述 | 语法示例 |
---|---|---|
STRUCT | 和C语言中的struct类似,都可以通过“点”符号访问元素内容。例如:如果某个列的数据类型是struct{first string,last string},那么第一个元素可以通过字段.first来引用 | struct() 例如 structStreet:String,city:string |
MAP | MAP是一组键值对元组集合,使用数组表示法可以访问数据。例如:如果某个列的数据类型是MAP,其中的键值对是’first’->‘join’,‘last’->‘doe’,那么可以通过字段名’last’获取最后一个元素 | map() 例如 map<String,int> |
ARRAY | 数组是一组具有相同类型和名称的变量的集合。这些变量成为数据的元素,每个元素都有一个编号,编号从零开始。例如值为{‘join’,‘doe’},那么第二个元素可以通过数据名[1]进行引用 | Array() 例如 array |
3.2.1 Array
-- 表数据
河南 郑州,开封,周口,新乡
浙江 杭州,宁波,台州
--建表
create table t_province(
province string,
city array(string)
)
row format delimited
fields terminated by ' '
collection items terminated by ','
;
--导入数据
load data local inpath '/data/province.txt' into table t_province;
--查询数据
select * from province;
河南 ["郑州","开封","周口","新乡"]
浙江 ["杭州","宁波","台州"]
--炸裂函数
select explode(city) from t_province;
郑州
开封
周口
新乡
杭州
宁波
台州
-- lateral view
-- lateral view用于和split, explode等UDTF一起使用
-- 它能够将一列数据拆成多行数据,在此基础上可以对拆分后的数据进行聚合。
select province,scity from t_province lateral view explode(city) city as scity;
河南 郑州
河南 开封
河南 周口
河南 新乡
浙江 杭州
浙江 宁波
浙江 台州
3.2.2 Map
-- 表数据
河南 郑州:1,开封:1,周口:2,新乡:3
浙江 杭州:1,宁波:2,台州:3
-- 建表
create table t_province(
province string,
items map<string,int>
)
row format delimited
fields terminated by ' '
collection items terminated by ','
map keys terminated by ':'
;
-- 导入数据
load data local inpath '/data/province.txt' into table t_province;
-- 查询数据
select * from t_partition;
河南 {"郑州":1,"开封":1,"周口":2,"新乡":3}
浙江 {"杭州":1,"宁波":2,"台州":3}
-- 炸裂函数
select explode(items) from t_province;
郑州 1
开封 2
周口 3
新乡 4
杭州 1
宁波 2
台州 3
--lateral view explode()
select name,itemname,num from t_province
lateral view explode(items) items as itemname,num;
河南 郑州 1
河南 开封 2
河南 周口 3
河南 新乡 4
浙江 杭州 1
浙江 宁波 2
浙江 台州 3
3.2.3 Struct
-- 数据
张三 浙江省,杭州市,西湖区
罗某 上海市,浦东区,街道
-- 建表
create table t_province(
name string,
addr struct<province:string,city:string,street:string>
)
row format delimited
fields terminated by ' '
collection items terminated by ','
;
-- 导入数据
load data local inpath '/data/province.txt' into table t_province;
-- 查询
select * from t_province;
张三 {"province":"浙江省","city":"杭州市","street":"西湖区"}
罗某 {"province":"上海市","city":"浦东区","street":"街道"}
--查询
select name,addr.province,addr.city,addr.street from t_province;
张三 浙江省 杭州市 西湖区
罗某 上海市 浦东区 街道
4 DDL数据(data definition language)数据定义语言
4.1 创建数据库
create database if not exists db_hive ;
默认存储路径是/usr/hive/warehouse/*.db
create database db_hive2 location ‘/db_hive2.db’;
创建一个数据库,指定数据库在HDFS上存储的位置
4.2 查询数据库
show databases;
show databases like ‘db_’;//过滤显示查询的数据库
desc database db_hive;//显示数据库信息
desc database extended db_hive;//显示数据库详细信息
use db_hive;//切换数据库
4.3 删除数据库
drop database if exists db_hive;//判断数据库存在并且删除
drop database db_hive cascade;//强制删除数据库
4.4 创建表
字段 | 说明 |
---|---|
cteate table (if not exists) | 创建一个指定名字的表,如果存在则先删除 |
external | 指定一个实际路径,创建其外部表,在删除内部表的时候元数据和数据会一起被删除,而删除外部表只会删除元数据不会删除数据 |
commit | 为表和列添加注释 |
partitioned by | 创建分区表 |
clustered by | 创建分桶表 |
sorted by | 不常用,对桶中的一个或多个列另外排序 |
row format 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, …)] Hive通过Serde确定表的具体列的数据。 SerDe是Serialize、Deserilize的简称,hive使用serde进行对象的序列话和反序列化 |
stored ad | SEQUENCEFILE(二进制序列文件)、 TEXTFILE(文本)、 RCFILE(列式存储格式文件) |
location | 指定HDFS上的存储位置 |
as | 后跟查询语句,根据查询结果创建表 |
like | 允许用户复制现有的表结构,但是不复制数据 |
4.4.1 管理表
默认创建的表都是所谓的管理表,也被成为内部表。这种表,Hive会控制着数据的生命周期。Hive默认情况下会将这些表的数据存储在由配置项目定义的目录下(/user/hive/warehouse)
4.4.2 外部表
外部表表示Hive认为其并非完全拥有这份数据。删除该表不会删除掉这份数据,不过描述表的元数据信息会被删除掉
4.4.3 管理表和外部表的应用场景
每天将收集到的网站日志定期流入HDFS文件中。在外部表(原始日志表)的基础上做大量的统计分析。用到的中间表,结果表使用内部表存储,数据通过SELECT+INSERT进入内部表。
4.4.4 管理表和外部表的互相转换
desc formatted student;//查询表类型
alter table student set tblproperties(‘EXTERNAL’ = ‘TRUE’);//修改内部表为外部表
alter table student set tblproperties(‘EXTERNAL’ = ‘false’);//修改外部表为内部表
tips:
(‘EXTERNAL’=‘TRUE’)和(‘EXTERNAL’=‘FALSE’)为固定写法, 区分大小写!
4.5 修改表
4.5.1 重命名表
alter table table_name rename to new_table_name;
4.5.2 增加、修改、替换列信息
- 更新列
alter table dept change column dept name desc String;//将dept的name改成String类型
- 增加
alter table dept add columns(deptdesc string);
- 替换
alter table dept replace columns(deptno string,dname string,loc string);
- ADD是代表新增一字段,字段位置在所以列后面(partition 列前)
- replace则是表示替换表中所有的字段
5 DML数据操作(data manipulation language)数据操作语言
5.1 数据导入
load data [local] inpath ‘date path’ [overwrite] into table student [partition (partcol1=val1.)]
指令 | 含义 |
---|---|
load data | 表示加载数据 |
local | 表示从本地加载数据到hive,否则从HDFS加载数据到hive |
inpath | 表示加载数据的路径 |
overwrite | 表示覆盖表中已有数据,否则表示追加 |
into table | 表示加载到哪张表 |
student | 表示具体的表 |
partition | 表示上传到指定分区 |
- 上传数据
hdfs dfs -put /opt/data/student.txt /user/hive;
- 创建表
create table student(id string, name string) row format
delimited fields terminated by ‘\\t’;
- 导入数据
load data inpath ‘/user/hive/student.txt’ overwrite into table student;
5.2 通过查询语句向表中插入数据
- 基本插入数据
insert into table student values(1,‘zxy’),(2,‘zhou’)
- 基本模式插入
insert overwrite table student select id,name from students where month = ‘202107’
insert into :以追加的方式插入到表或分区,原有数据不会删除
insert overwrite:会覆盖表中已存在的数据
- 多分区插入模式
from student
insert overwrite table student partition(month = ‘202107’)
select id,name where month = ‘202108’
insert overwrite table studdent partition(month = ‘202106’)
select id,name where month = ‘202109’
5.3 数据导出
5.3.1 Insert导出
- 将查询结果导出到本地
insert overwrite local directory ‘/opt/apps/student’ select * from student;
- 将查询结果格式化导出到本地
insert overwrite local directory ‘/opt/apps/student’
row format delimited
fields terminated by ‘\\t’
select * from student;
- 将查询结果导出到HDFS
insert overwrite directory ‘/user/student’
row format delimited
fields terminated by ‘\\t’
select * from student;
5.3.2 Hadoop命令导出到本地
- hdfs命令导出
hdfs dfs -get /user/hive/student.txt /opt/apps/student.txt
- hive shell 命令导出
hive -e ‘select * from student;’ > /opt/apps/student/student.txt
- export导出到hdfs上
export table student to ‘/user/hive/student’
export 和 import 主要用于两个 Hadoop 平台集群之间 Hive 表迁移。
5.3.3 sqoop导出
5.3.4 清楚表中数据(Truncate)
truncate table student;
注意: Truncate 只能删除管理表, 不能删除外部表中数据
6 查询
6.1 基本查询
6.1.1 tips
SQL语言大小写不敏感
SQL可以写在一行或者多行
关键字不能被缩写也不能分行
各子句一般要分行写
使用缩进提高可读性
6.1.2 别名
重命名一个列
便于计算
紧跟列名,也可以在列名和别名之间加入关键字‘AS’
6.1.3 算术运算符
运算符 | 描述 |
---|---|
A+B | A和B相加 |
A-B | A减去B |
A*B | A和B相乘 |
A/B | A除以B |
A%B | A对B取余 |
A&B | A和B按位取与 |
A|B | A和B按位取或 |
A^B | A和B按位取异或 |
~A | A按位取反 |
6.1.4 常用函数
函数 | 案例 |
---|---|
count | select count(*) cnt from emp; |
max | select max(age) max_age from emp; |
min | select min(age) min_age from emp; |
sum | select sum(age) sum_age from emp; |
avg | select avg(age) avg_age from emp; |
6.1.5 Limit
Limit子句用于限制返回的行数
select * from emp limit 5;
6.1.6 where语句
使用where语句,将不满足条件的过滤掉
where子句紧随from子句
select * from emp where sal in (1500,5000);
6.1.7 Like和RLike
- like
%代表零个或者多个字符
_表示一个字符
- Rlike
RLIKE可以使用正则表达式这个强大的功能
select * from emp where name RLIKE ‘[A]’;
6.2 分组
6.2.1 GROUP BY语句
GROUP BY语句经常和聚合函数一起使用,按照一个或者多个队列结果进行分组,然后对每个组执行聚合操作
6.2.2 Having语句
- having和where的不同点
where后面不能些分组函数,而having后面可以使用分组函数
having只用于group by分组统计语句
6.3 Join语句
- 尽量避免使用子查询,但是子查询不可避免
- 尽量避免过多的join查询,但是join查询不可避免
- 尽量不要使用in或者not in的语法
- 一定要使用小表驱动大表,因为hive在做查询的时候,首先缓存一部分数据(查看左边的表)。说白了就是数据量小的表尽量先查。
- 表别名的好处
使用别名可以简化查询
使用别名可以提高执行效率
交叉查询:access join: 产生笛卡尔积的查询
inner join
/join
left outer join
/left join
right outer join
/right join
full outer join
/full join
left semi join
:左半连接
6.3.1 数据
表A:
id name
1 a
2 b
3 c
4 d
表B:
id name
2 b
4 d
5 e
6.3.2 内连接(inner join)
select
A.id A_id,
A.name A_name,
B.id B_id,
B.name B_name
from
A join B
on A.id=B/.id
A_id | A_name | B_id | B_name |
---|---|---|---|
2 | b | 2 | b |
4 | d | 4 | d |
6.3.3 左外连接(left join)
select
A.id A_id,
A.name A_name,
B.id B_id,
B.name B_name
from
A left join B
on A.id=B/.id
A_id | A_name | B_id | B_name |
---|---|---|---|
1 | a | null | null |
2 | b | 2 | b |
3 | c | null | null |
4 | d | 4 | d |
6.3.4 右外连接(right join)
select
A.id A_id,
A.name A_name,
B.id B_id,
B.name B_name
from
A right join B
on A.id=B/.id
A_id | A_name | B_id | B_name |
---|---|---|---|
2 | b | 2 | b |
4 | d | 4 | d |
null | null | 5 | e |
6.3.5 全连接(full join)
select
A.id A_id,
A.name A_name,
B.id B_id,
B.name B_name
from
A join B
on A.id=B/.id
A_id | A_name | B_id | B_name |
---|---|---|---|
1 | a | null | null |
2 | b | 2 | b |
3 | c | null | null |
4 | d | 4 | d |
null | null | 5 | e |
6.3.6 左半连接
select
from
B left semi join A
on A.id=B.id
B.id | B.name |
---|---|
2 | b |
4 | d |
6.3.7 多表连接
tips:
连接n个表,至少需要n-1个条件
大多数情况下, Hive 会对每对 JOIN 连接对象启动一个 MapReduce 任务。本例中会首先
启动一个 MapReduce job 对表 e 和表 d 进行连接操作,然后会再启动一个 MapReduce job 将
第一个 MapReduce job 的输出和表 l;进行连接操作。
注意:为什么不是表 d 和表 l 先进行连接操作呢?这是因为 Hive 总是按照从左到右的
顺序执行的。
优化: 当对 3 个或者更多表进行 join 连接时,如果每个 on 子句都使用相同的连接键的
话,那么只会产生一个 MapReduce job。
6.3.8 笛卡尔积
笛卡尔积会在下面条件下产生
- 省略连接条件
- 连接条件无效
- 所有表中的所有行互相连接
6.3.9 in
select * from A where A.id in (select B.id from B)
6.3.10 子查询
总体来说,hive的子查询和sql的子查询是一样的。子查询只能出现在from之后或者where之后
子查询对别名的识别特别严格,任何的可以取别名的地方,定义一个别名
-- 在SQL中没错,但是hive中错
select * from A where A.id = (
select B.id from B where B.id = 2
);
--在hive中使用方法
select * from A where A.id in (
select B.id from B where B.id = 2
);
6.4 排序
6.4.1 全局排序(Order by)
全局排序,只有一个Reducer
- 使用OEDER BY子句排序
ASC(ascend):升序(默认)
DESC(descend):降序
6.4.2 每个Reduce内部排序(Sort by)
桶内有序,不保证全局有序
sort by : 对于大规模的数据集order by的效率非常低。很多情况下,并不需要全局排序,此时可以使用sort by
sort by为每个reduce产生一个排序文件,每个Reduce内部进行排序,对全局结果集来说不是排序
- 设置reduce个数
set mapreduce.job.reduces=3;
- 查看设置reduce个数
set mapreduce.job.reduces;
6.4.3 分区(Distribute by)
Distribute By: 在有些情况下, 我们需要控制某个特定行应该到哪个 reducer, 通常是为
了进行后续的聚集操作。 distribute by 子句可以做这件事。 distribute by 类似 MR 中 partition
(自定义分区) ,进行分区,结合 sort by 使用。
对于 distribute by 进行测试,一定要分配多 reduce 进行处理,否则无法看到 distribute
by 的效果。
- tips
distribute by的分区规则是根据分区字段的hash码与reduce的个数进行模除后,余数相同的分到一个区。
Hive要求distribute by语句要写在sort by语句之前
6.4.4 Cluster By
当distribute by和sort by字段相同时,可以使用cluster by方式。
cluster by除了具有distribute by功能外,还具有sort by功能,但是排序只能是升序排序,不能指定排序规则为ASC或者DESC
select * from emp cluster by deptno;
select * from emp distribute by deptno sort by deptno;
7 分区表和分桶表
7.1 分区表
分区表其实就是对应一个HDFS文件系统上独立的文件夹,该文件夹是该分区所有的数据文件。HIve中的分区就是分目录,把一个大的数据集根据业务分割成小的数据集。在查询的时候通过where子句中的表达式选择查询所需要指定的分区,这样会提高查询的效率
7.2 分区表
-创建分区表
create table dept_partition (
deptno int,
dname string,
loc string
)
partitioned by (day string)
row format delimited
fields terminated by '\\t';
- 导入数据
load data local inpath '/opt/apps/dept_20210725.log' into table dept_partition partition(day='20210725')
load data inpath '/hive/scoures/dept_20210725.log' into table dept_partition partition(day='20210725')
- 查询分区
select * from dept_partition where day='20210725';
- 删除分区
alter table dept_partition drop partition(day='20210725')
- 查看分区表有多少分区
show partitions dept_partition;
- 查看分区表结构
desc formatted depta_partition;
tips:
分区字段不能是表中已经存在的数据,可以将分区字段看作表的伪列。
加载数据的时候必须指定分区
7.3 把数据直接上传到分区目录上,让分区表和数据产生关联的三种方式
7.3.1 上传数据后修复
- 上传数据
dfs -mkdir -p /user/dept_partition/day=20210725/hour=8
dfs -put /opt/apps/dept_20210725.log /user/dept_partition/day=20210725/hour=8
- 查询数据
select * from dept_partition where day=‘20210725’ and hour=‘8’
查询不到
- 修复数据
msck repair table dept_partition;
- 再次查询数据
select * from dept_partition where day=‘20210725’ and hour=‘8’
7.3.2 上传数据后添加分区
- 上传数据
dfs -mkdir -p /user/dept_partition/day=20210725/hour=8
dfs -put /opt/apps/dept_20210725.log /user/dept_partition/day=20210725/hour=8
- 添加分区
alter table ddept_partition add partition(day=‘20210725’,hour=‘8’)
- 查询数据
select * from dept_partition where day=‘20210725’ and hour =‘8’
7.3.3 创建文件夹后load数据到分区
- 上传数据
dfs -mkdir -p /user/dept_partition/day=20210725/hour=8
- 上传数据
load data local inpath ‘/opt/apps/dept_20210725.log’ into table dept_partiton partition(day=‘20210725’,hour=‘8’)
- 查询数据
select * from dept_partition where day=‘20210725’ and hour =‘8’
7.4 动态分区调整
7.4.1 开启动态分区
- 静态分区:加载数据的时候指定分区的值
- 动态分区:数据未知,根据分区的值创建分区
- 静态+动态
- hive-site.xml
## 开启动态分区功能(默认 true,开启)
<property>
<name>hive.exec.dynamic.partition</name>
<value>true</value>
</property>
##设置为非严格模式(动态分区的模式,默认 strict,表示必须指定至少一个分区为静态分区, nonstrict 模式表示允许所有的分区字段都可以使用动态分区。)
<property>
<name>hive.exec.dynamic.partition.mode</name>
<value>nonstrict</value>
</property>
##在所有执行 MR 的节点上,最大一共可以创建多少个动态分区。默认 1000
<property>
<name>hive.exec.max.dynamic.partitions</name>
<value>1000</value>
</property>
##在每个执行 MR 的节点上,最大可以创建多少个动态分区。 该参数需要根据实际的数据来设定。比如:源数据中包含了一年的数据,即 day 字段有 365 个值,那么该参数就需要设置成大于 365,如果使用默认值 100,则会报错。
<property>
<name>hive.exec.max.dynamic.partitions.pernode</name>
<value>100</value>
</property>
##整个 MR Job 中,最大可以创建多少个 HDFS 文件。默认 100000
<property>
<name>hive.exec.max.created.files</name>
<value>100000</value>
</property>
## 当有空分区生成时,是否抛出异常。一般不需要设置。默认 false
<property>
<name>hive.error.on.empty.partition</name>
<value>false </value>
</property>
<property>
<name>hive.exec.mode.local.auto.input.files.max</name>
<value>4</value>
</property>
<property>
<name>hive.exec.mode.local.auto</name>
<value>true</value>
</property>
<property>
<name>hive.exec.mode.local.auto.inputbytes.max</name>
<value>134217728</value>
</property>
7.5 分桶
桶是比分区更细粒度的划分。当我们对表中的数据进行join的时候势必回产生笛卡尔积。桶就是可以帮助我们减少笛卡尔积。
分桶表的建立不可以直接导入数据,需要建立中间表
- 设置reduce个数,即为分桶数量
set mapreduce.job.reduces=4
7.5.1 准备数据
1,zxy,man,18,java
2,zxy2,man,18,java
3,zxy3,man,18,swift
4,zxy4,man,18,java
5,zxy5,man,18,objective-c
6,zxy6,man,18,java
7,zxy7,man,18,java
8,zxy8,man,18,c#
7.5.2 建立中间表
create table stu(
sno int,
sname string,
gender string,
age int,
subject string
)
row format delimited
fields terminated by ','
;
load data local inpath '/data/stu.txt' into table t_stu;
7.5.3 分桶查询
--方法一
select * from stu cluster by(sno);
--方法二
select * from t_stu distribute by(sno) sort by(sno);
1,zxy,man,18,java
4,zxy4,man,18,java
2,zxy2,man,18,java
5,zxy5,man,18,objective-c
3,zxy3,man,18,swift
6,zxy6,man,18,java
7,zxy7,man,18,java
8,zxy8,man,18,c#
7.5.4 建立分桶表
create table t_bulk(
sno int,
sname string,
gender string,
age int,
subject string
)
clustered by(sno) sorted by(sno) into 4 buckets
row format delimited
fields terminated by ','
;
7.5.5 导入分桶表
--方法一
insert into t_bulk
select * from stu cluster by(sno);
--方法二
insert into t_bulk distribute by(sno) sort by(sno desc);
7.5.6 采样查询
--1. 不压缩,不拉伸
select * from t_bulk tablesample(bucket 1 out of 4) -- 查询4桶中的第1桶
select * from t_bulk tablesample(bucket 2 out of 4) -- 查询4桶中的第2桶
-- 查询4桶中的第1、3桶,压缩,查询一半
select * from t_bulk tablesample(bucket 1 out of 2)
-- 查询4桶中的第1桶一部分,拉伸,查询1/8
select * from t_bulk tablesample(bucket 1 out of 8)
--2.取多少行
select * from t_bulk limit 4;
select * from t_bulk tablesample(4 rows);
--3.按百分比抽样
select * from t_bulk tablesample(10 percent);
--4. 按照容量大小
select * from t_bulk tablesample(11B); -- 抽样11个字节:K KB B M G T
--5. 抽取随机3行
select * from t_bulk order by rank() limit 3;
--6. 条件抽样
select * from t_source tablesample(bucket 2 out of 4) where sno = 1; -- 查询4桶中的一半并且需要sno=1
7.6 分区分桶表
需要开启非严格模式,若配置文件没有修改,可使用命令行操作
set hive.exec.dynamic.partition.mode=nonstrict;
7.6.1 中间表
create table stu(
id int,
name string,
sex int
)
row format delimited
fields terminated by ' '
;
load data local inpath '/data/stu.txt' into table stu;.
7.6.2 创建分桶分区表
create table t_part_bulk(
id int,
name string
)
partitioned by(sex int)
clustered by(id) into 4 buckets
row format delimited
fields terminated by ' '
;
7.6.3 向表中导入数据
set mapreduce.job.reduces=4;
insert into t_part_bulk partition(sex)
select id,name,sex from stu cluster by(id)
tips:
1.分桶的桶数和reducer的个数要相同
2.产生的文件是首次运行结果一共的文件数,也就是四个桶产生四个文件,分别放在两个不同的分区目录下
8 窗口函数
8.1 窗口函数定义
窗口函数又叫做开创函数,他是一种分析的函数,专门可以解决报表类型的需求分析。他专门用于计算基于组的某种聚合。对于每个组返回返回是多行,也就是聚合函数的分组只有显示一行
开窗函数指定了分析函数的窗口大小,窗口的大小会根据行的变化而变化
8.2 Over函数
8.2.1 数据
姓名,购买日期以上是关于Hive万字总结的主要内容,如果未能解决你的问题,请参考以下文章
Hive从入门到精通,HQL硬核整理四万字,全面总结,附详细解析,赶紧收藏吧!!
五万字,57道hadoop大厂高频面试题,每一字都细心打磨,强烈建议收藏!