hive的一些重要的知识点

hive的一些重要的知识点

(基于Hadoop的一个数据仓库工具)
基本组成:
用户接口:包括 CLI、JDBC/ODBC、WebGUI。
元数据存储:通常是存储在关系数据库如 mysql , derby中。
解释器、编译器、优化器、执行器。

1.内部表,外部表,相同与区别

相同:

都是表

区别:

内部表数据由Hive自身管理,外部表数据由HDFS管理;

内部表数据存储的位置是hive.metastore.warehouse.dir(默认:/user/hive/warehouse),外部表数据的存储位置由自己制定;

删除内部表会直接删除元数据(metadata)及存储数据;删除外部表仅仅会删除元数据,HDFS上的文件并不会被删除;

对内部表的修改会将修改直接同步给元数据,而对外部表的表结构和分区进行修改,则需要修复(MSCK REPAIR TABLE table_name;)

  1. 临时表(创建表时添加TEMPORARY关键字)和永久表
  2. 内部表&外部表

a) 删除内部表时,表结构(元信息)和表对应的数据会一同被删除

b) 删除外部表时,只有表结构被删除

注意:创建表时如果指定了表的位置,建议表的类型是external

  1. 分区表

表内的数据按照地域、时间等业务纬度,在表内将数据进一步细分成分区。

  1. 分桶表

在分区表的基础上,将分区内的数据进一步细分成桶。

2.分区表 技术与意义

作用:
将表内的数据按照业务纬度列(常见的有:时间、地域、类别)进行进一步细分,

  1. 可以减少数据冗余
  2. 提高特定(指定分区)查询分析的效率
分区表的说明:

分区表的一个分区对应hdfs上的一个目录

分区表包括静态分区表和动态分区表,根据分区会不会自动创建来区分

多级分区表,即创建的时候指定 PARTITIONED BY (event_month string,loc string),根据顺序,级联创建 event_month=XXX/loc=XXX目录,其他和一级的分区表是一样的

静态分区表

创建静态分区表,加载数据:
use test1;
drop table test1.order_created_partition;
CREATE TABLE order_created_partition (
order_number string,
event_time string
)
PARTITIONED BY (event_month string)
ROW FORMAT DELIMITED FIELDS TERMINATED BY “\t”;
– 建表语句,指定分区字段为event_month,这个字段是伪列
– 会在数据load到表的这个分区时,在hdfs上创建名为event_month=2017-12的子目录
LOAD DATA LOCAL INPATH “/order_created.txt”
OVERWRITE INTO TABLE order_created_partition
PARTITION (event_month=‘2017-12’);
– 使用 hdfs dfs -cat …/order_created_partition/event_month=2017-12/order_created.txt
– 查看数据文件中并没有event_month这一列
select * from test1.order_created_partition;
– 分区表全表扫描,不推荐
select * from test1.order_created_partition
where event_month=‘2017-12’;
– 使用where子句,过滤分区字段,遍历某个分区
– 以上两个SQL可以查到列event_month信息
– 而使用hdfs dfs -cat看不到该列,说明分区表的分区列是伪列
– 实际上是hdfs中的分区目录的体现
添加分区,load数据:
alter table test1.order_created_partition add partition (event_month=‘2018-01’);
LOAD DATA LOCAL INPATH “/tmp/order_created.txt”
OVERWRITE INTO TABLE order_created_partition
PARTITION (event_month=‘2018-01’);
– 添加一个分区,将一模一样的数据文件加载到该分区
select * from test1.order_created_partition
where event_month=‘2018-01’;
– 查到了该分区的记录
LOAD DATA LOCAL INPATH “/order_created.txt”
INTO TABLE order_created_partition
PARTITION (event_month=‘2018-01’);
select * from test1.order_created_partition
where event_month=‘2018-01’;
– 不使用OVERWRITE参数,会追加数据到分区
LOAD DATA INPATH “/user/hive/warehouse/test1.db/order_created_partition/event_month=2017-12/order_created.txt”
INTO TABLE order_created_partition
PARTITION (event_month=‘2018-01’);
– 如果从hdfs中加载数据,则原来的路径文件被转移掉

可以看出,所谓的分区,是人为定义的,跟业务数据实际上是不是属于该分区没关系,比如将相同的数据分别插入两个分区中,再比如插入的数据有2017-12月份的和2018-01月份的数据
删除分区:
alter table test1.order_created_partition
drop partition (event_month=‘2018-01’);
从hdfs中已经看不到event_month=2018-01的分区子目录了
查询装入数据:
insert overwrite table order_created_partition
partition(event_month=‘2017-11’)
select order_number,event_time
from order_created_partition
where event_month=‘2018-02’;
使用查询装入数据到分区中,分区可以是当前不存在的
因为查询的是分区表,需要注意伪列和被装入的分区表列的对应关系
手工创建hdfs目录和文件,添加分区的情况:
静态分区表如果手工创建对应的hdfs目录上传文件,而不使用分区创建命令和load数据到分区的命令,分区表中无法查到该分区信息,需要刷新,这种添加分区的途径是不合法的:
linux语句
hdfs dfs -mkdir -p /user/hive/warehouse/test1.db/order_created_partition/event_month=2018-02
hdfs dfs -put /tmp/order_created.txt /user/hive/warehouse/test1.db/order_created_partition/event_month=2018-02
hdfs dfs -ls /user/hive/warehouse/test1.db/order_created_partition/event_month=2018-02
hive语句:
select * from test1.order_created_partition
where event_month=‘2018-02’;
此时是查不到该分区的
MSCK REPAIR TABLE order_created_partition;
修复表信息之后可以查询
show partitions order_created_partition;
查看该表的所有分区

*动态分区表

use test1;
select * from emp;
根据从前实验创建的emp表
将emp表的数据按照部门分组,并将数据加载到其对应的分组中去
create table emp_partition(
empno int,
ename string,
job string,
mgr int,
hiredate string,
sal double,
comm double)
PARTITIONED BY (deptno int)
row format delimited fields terminated by ‘\t’;
根据部门编号分区,原表中的部门编号字段就没有必要创建了
而是由分区表创建的伪列来替代
set hive.exec.dynamic.partition.mode=nonstrict;
设置动态分区模式为非严格模式
insert into table emp_partition partition(deptno)
select empno,ename,job,mgr,hiredate,sal,comm ,deptno from emp;
动态分区表的数据插入语句
– partition(deptno) 而不是 partition(deptno=XXX)
– select 子句从原表查出来的列数和列序要和分区表列数和列序保持一致
– select 子句最后一列要为分区表的分区列
不在需要where子句
设置动态分区模式为非严格模式
– set hive.exec.dynamic.partition.mode=nonstrict;

3.分通表 分区与意义

分桶表本质

与分区表类似,hive表中、分区中均可以指定列,然后对其分桶。分桶表是对列值取哈希值的方式,将不同数据放到不同文件中存储。对于hive中每一个表、分区都可以进一步进行分桶。分桶列与分区列使用的列一般不同。

分桶表与分区表区别

分区表根据指定的列将表进行分区,列值相同的数据会分到同一个分区。分桶表一般是在分区表的基础上,对其他业务列进行分桶。

分桶表优点

(1)获得更高的查询处理效率。桶为表加上了额外的结构,Hive 在处理有些查询时能利用这个结构。具体而言,连接两个在(包含连接列的)相同列上划分了桶的表,可以使用 Map 端连接 (Map-side join)高效的实现。比如JOIN操作。对于JOIN操作两个表有一个相同的列,如果对这两个表都进行了桶操作。那么将保存相同列值的桶进行JOIN操作就可以,可以大大较少JOIN的数据量。

例如:雇员表和部门表两个表,指定雇员表中的所属部门id列为分桶列,指定部门表中的id为分桶列。

(2)使取样(sampling)更高效。在处理大规模数据集时,在开发和修改查询的阶段,如果能在数据集的一小部分数据上试运行查询,会带来很多方便。

4.窗口函数

LEAD lead

可以选择指定要引导的行数。如果未指定要引导的行数,则前导是一行。

当当前行的前导超出窗口末尾时返回null。

LAG lag

可以选择指定滞后的行数。如果未指定滞后行数,则滞后为一行。

当当前行的延迟在窗口开始之前延伸时,返回null。

FIRST_VALUE first_value

这最多需要两个参数。第一个参数是您想要第一个值的列,第二个(可选)参数必须是false默认的布尔值。如果设置为true,则跳过空值。

LAST_VALUE last_value

这最多需要两个参数。第一个参数是您想要最后一个值的列,第二个(可选)参数必须是false默认的布尔值。如果设置为true,则跳过空值

5.排名函数,给出案例 实现

6.distribute by、partition by与cluster by的区别

distribute by

distribute by是控制在map端如何拆分数据给reduce端的。hive会根据distribute by后面列,对应reduce的个数进行分发,默认是采用hash算法。sort by为每个reduce产生一个排序文件。在有些情况下,你需要控制某个特定行应该到哪个reducer,这通常是为了进行后续的聚集操作。distribute by刚好可以做这件事。因此,distribute by经常和sort by配合使用。

注:Distribute by和sort by的使用场景

1.Map输出的文件大小不均。

2.Reduce输出文件大小不均。

3.小文件过多。

4.文件超大。

cluster by

cluster by除了具有distribute by的功能外还兼具sort by的功能。但是排序只能是倒叙排序,不能指定排序规则为ASC或者DESC。

partition by

partition by 是按照字段进行分区,distribute by是控制数据到哪个reducer,而partition by是在map端进行分区,在对数据进行计算的时候是分区计算的,每个分区的数据在一起计算。

7.sort by与order by的区别

sort by 和 order by的区别是前者给每一reducer上的所有行进行排序,后者保证在数据结果上都有序。也就是说,如果使用超过一个reducer,使用sort by可能给出部分有序的结果。

你可能感兴趣的:(hive的一些重要的知识点)