文章目录

1.内部表和外部表的区别,以及各自的使用场景

内部表
如果 Hive 中没有特别指定,则默认创建的表都是管理表,也称内部表。由Hive负责管理表中的数据,管理表不共享数据。删除管理表时,会删除管理表中的数据和元数据信息 。

外部表
当一份数据需要被共享时,可以创建一个外部表指向这份数据 。
删除该表并不会删除掉原始数据,删除的是表的元数据。这样外部表相对来说更加安全些,数据组织也更加灵活,方便共享源数据 。当表结构或者分区数发生变化时,需要进行一步修复的操作。

2.Hive 中的压缩格式 TextFile、SequenceFile、RCfile 、ORCfile 各有什么区别

1.TextFile是默认格式,存储方式为行存储,数据不做压缩,磁盘开销大,数据解析开销大。
可以结合Gzip,Bzip2使用,但是这种压缩方式压缩后的文件不支持split,从而无法对数据进行并行处理。在反序列化的过程中会比SequenceFile的开销高10多倍,必须判断是否是分隔符和行结束符。

2.SequenceFile:
是Hadoop API 提供的一种二进制文件支持,存储方式是行存储,具有可分割,可压缩的特点。
SequenceFile 支持三种压缩选择:NONE, RECORD, BLOCK,建议用Block压缩方式

3.RCFile:
存储方式为数据按行分块,每块列存储。结合了行和列存储的特点。
RCFile 保证同一行的数据位于同一节点,因此元组重构的开销很低,而且,像列存储一样,RCFile 能够利用列维度的数据压缩,并且能跳过不必要的列读取

4.ORCFile:
存储方式为数据按行分块 每块按照列存储。
压缩快,快速列存取。
效率比RCFile高,是RCFile存储的改良版。

5.总结
相比 TEXTFILE 和 SEQUENCEFILE,RCFILE 由于列式存储方式,数据加载时性能消耗较大,但是具有较好的压缩比和查询响应。
数据仓库的特点是一次写入、多次读取,因此,整体来看,RCFILE 相比其余两种格式具有较明显的优势。

3.所有的 Hive 任务都会有 MapReduce 的执行吗

不是,从 Hive0.10.0 版本开始,对于简单的不需要聚合的类似 SELECT from LIMIT n 语句,不需要起 MapReduce job,直接通过 Fetch task 获取数据。

4.Hive 的函数:UDF、UDAF、UDTF 的区别

UDF:单行进入,单行输出
UDAF:多行进入,单行输出
UDTF:单行进入,多行输出

5. Hive 桶表

桶表是对数据进行哈希取值,然后放到不同文件中存储 。

数据加载到桶表时,会对字段取 hash 值,然后与桶的数量取模。把数据放到对应的文件中。物理上,每个桶就是表(或分区)目录里的一个文件,一个作业产生的桶(输出文件)和 reduce 任务个数相同 。

桶表专门用于抽样查询,是很专业性的,不是日常用来存储数据的表,需要抽样查询时,才创建和使用桶表。

6.Hive 表关联查询,如何解决数据倾斜的问题

1.定位原因
某些 SQL 语句本身就有数据倾斜等原因造成的 reduce 上的数据量差异过大。

2.如何避免
对于 key 为空产生的数据倾斜,可以对其赋予一个随机值

3.解决方案

1>参数调优

hive.map.aggr = true 

hive.groupby.skewindata=true

有数据倾斜的时候进行负载均衡,当选项设定位 true,生成的查询计划会有两个 MR Job。第一个 MR Job 中,Map 的输出结果集合会随机分布到 Reduce 中,每个 Reduce 做部分聚合操作,并输出结果,这样处理的结果是相同的 Group By Key 有可能被分发到不同的 Reduce 中,从而达到负载均衡的目的;

第二个 MR Job 再根据预处理的数据结果按照 Group By Key 分布到 Reduce 中(这个过程可以保证相同的 Group By Key 被分布到同一个 Reduce 中),最后完成最终的聚合操作

2>SQL调优

①选用 join key 分布最均匀的表作为驱动表。做好列裁剪和 filter 操作,以达到两表做 join 的时候,数据量相对变小的效果。

② 大小表 Join:使用 map join 让小的维度表(1000 条以下的记录条数)先进内存。在map 端完成 reduce。

③ 大表 Join 大表:把空值的 key 变成一个字符串加上随机数,把倾斜的数据分到不同的 reduce 上,由于 null 值关联不上,处理后并不影响最终结果。

④ count distinct 大量相同特殊值:count distinct 时,将值为空的情况单独处理,如果是计算 count distinct, 可以不用处理,直接过滤,在最后结果中加 1。如果还有其他计算,需要进行 group by,可以先将值为空的记录单独处理,再和其他计算结果进行 union。

7.Hive的窗口函数

1.RANK()

RANK() 排序相同时会重复,总数不会变
DENSE_RANK()排序相同时会重复,总数会减少
ROW_NUMBER() 会根据顺序计算

2.OVER()

指定分析函数工作的数据窗口大小,这个数据窗口大小可能会随着行的变而 变化

1.CURRENT ROW:当前行
2.n PRECEDING: 向前n行
3.n FOLLOWING: 向后n行
4.UNBOUNDED : 起点
5.LAG(col,n) :往前第 n 行数据
6. LEAD(col,n):往后第 n 行数据

8.Tez 引擎优点

Tez 可以将多个有依赖的作业转换为一个作业,这样只需写一次 HDFS,且中间节点较少,从而大大提升作业的计算性能。

Mr 引擎:多 job 串联,基于磁盘,落盘的地方比较多。虽然慢,但一定能跑出结果。一般处理,周、月、年指标 。
Spark 引擎:虽然在 Shuffle 过程中也落盘,但是并不是所有算子都需要 Shuffle,尤其 是多算子过程,中间过程不落盘 DAG 有向无环图。兼顾了可靠性和效率。一般处理天指标。
Tez 引擎:完全基于内存。注意:如果数据量特别大,慎重使用。容易 OOM。一般用于快速出结果,数据量比较小的场景。

9.Hive-DDL语法

1.建表语法

Hive面试题_2_数据仓库
exrernal关键字:表示外部表,默认为内部表,删除内部表的时候,数据和表同时删除,删除外部表的时候,仅仅删除表的定义,数据保留,在生产环境中,多用外部表

#内部表转外部表
alter table t1 set tblproperties("EXTERNAL" = "TRUE")

partition by:对表中数据进行分区

clustered by:创建分桶表,指定分桶字段

tblproperties:定义表的属性

location:数据位于HDFS的位置

stored as SEQUENCEFILE | TEXTFILE | RCFILE:存储为什么什么存储形式

2.分区表

--创建表
create table if not exist t1(
id int,
name string,
hobby array,
addr map
)
partitioned by (dt string) #按照时间进行分区
row format delimited
fields terminated by ';'
collection items terminated by ','
map keys terminated by ':'

--加载数据
load data local inpath "/home/hadoop/data/t1.dat" into table t1
partition(dt="2021-12-09'")

3.分桶表
当单个的分区或者表的数据过大,分区不能更细粒度的划分数据,就需要使用分桶技术将数据划分成更细的粒度。
分桶字段.hashcode % 分桶数

--创建分桶表
creat table course(
id int,
name string,
score int
)
clustered by (id) into 3 buckets
row format delimited
fields terminated by "\t";

--创建普通表
creat table course_common(
id int,
name string,
score int
)
row format delimited
fields terminated by "\t";

--普通表加载数据
load data local inpath '/home/hadoop/data/course.dat' into table course_common

--通过insert...select...给桶表加载数据
insert into table course select * from course_common;

--观察分桶数据,数据按照:(分区字段,hashcode)%(分桶数进行分区)

4.修改表/删除表

--修改表名
alter table course_common rename to course_common1 ;
--修改列名
alter table course_common1 change name subjuct string ;
--修改字段类型
alter table course_common1 change id id srting #int改string ;
--增加列
alter table course_common1
add columns(common string) ;
--修改删除列
alter table course_common1
replace columns(
idx string,subjucty string,scorez string) ;
--删除表
drop table course_common1 ;

5.表的分类

1.内部表
2.外部表
3.分区表
4.分桶表

6.加载数据

load data [local] inpath 'filepath'
[overwrite] into tablename [partition(partclo1=val1,partclo2=val2...)]

7.插入数据

create table tabc(
id int,
name string,
area string
)
partitioned by (month string)

#指定分区插入数据
insert into tabc
partition(month = "202001")
values (1,'zhangsan','BJ'),(2,'lisi','SH')

#从表中插入数据
from tabc
insert overwrite table tabc partition(month = '202002')
select id,name,area where month = '202001'
insert overwrite table tabc partition(month = '202002')
select id,name,area where month = '202001' or month = '202002'

Hive面试题_2_数据_02

8.导出数据

--将结果导出到本地
insert overwrite local directory '/home/hadoop/data/tabc'
select * from tabc;

--将结果格式化输出到本地
insert overwrite local directory '/home/hadoop/data/tabc'
row formate delimited fields terminated by ' '
select * from tabc;

--将结果查询导出到HDFS
insert overwrite directory '/user/hadoop/data/tabc1'
row formate delimited fields terminated by ' '
select * from tabc;

--dfs命令导出数据到本地,本质是执行数据的拷贝
dfs -get /user/hive/warehouse/mydb.db/tabc/month=202001 /home/hadoop/data/tabc4

--hive命令导出数据到本地,执行程序将查询结果重定向到文件
hive -e "select * from mydb.tabc" > a.log

--export 导出数据到HDFS,使用export导出数据时,不仅有数还有表的元数据信息
export table tabc to '/user/hadoop/data/tabc4'

--export 导出的数据,可以使用import命令导入到hive表中
--使用like tname 创建的表结构与原表一致。create...as select...结构可能不一致
create table tabE like tabC
import table tabE from ''/user/hadoop/data/tabC4' ;

--截断表,清空数据(注意,仅能操作内部表)
truncate table tabE

--注意 外部表不能执行truncate操作,以下语句执行会出错
alter table tabC set tblroperties("EXTERNAL"="TRUE")
truncate table tabC;