1. 简述hive
Hive是一个构建在Hadoop之上的数据仓库工具,主要用于处理和查询存储在HDFS上的大规模数据。Hive通过将结构化的数据文件映射成表,并提供类SQL的查询功能,使得用户可以通过编写SQL语句来进行数据分析,而不需要编写复杂的MapReduce程序
2. 简述hive读写文件机制
Hive读写文件机制主要依赖Hadoop的HDFS(分布式文件系统)和MapReduce(计算框架)。Hive通过SQL语句转换成MapReduce任务,然后在Hadoop上执行。
写文件:
Hive执行INSERT语句时,会生成MapReduce作业。
Map阶段处理源数据,将数据转换成Hive指定的格式。
Reduce阶段收集数据,写入HDFS中Hive指定的表目录。
读文件:
Hive执行SELECT语句时,会生成MapReduce作业。
Map阶段扫描HDFS中的数据文件,读取数据。
Reduce阶段处理数据,最终返回结果。
Hive读写文件的机制简化了数据处理流程,通过SQL语句就可以实现数据的读写,而不需要直接操作MapReduce。
示例代码(插入数据到Hive表):
INSERT INTO TABLE my_table
SELECT column1, column2
FROM another_table
WHERE condition;
示例代码(从Hive表中读取数据):
SELECT column1, column2
FROM my_table
WHERE condition;
3. hive和传统数据库之间的区别
Hive和传统的数据库系统(如MySQL、PostgreSQL、Oracle等)有以下主要区别:
架构不同:Hive是构建在Hadoop上的,利用HDFS存储数据,使用MapReduce进行数据处理。而传统数据库则直接运行在本地硬件上。
数据更新:Hive主要用于数据分析,不支持在线更新,适合批处理。而传统数据库支持在线更新、删除和添加,适合事务处理。
数据存储位置:Hive的数据存储在HDFS中,而传统数据库通常存储在本地文件系统中。
执行引擎:Hive使用MapReduce作为执行引擎,而传统数据库有自己的执行引擎。
索引和优化:Hive对数据的操作依赖于MapReduce任务,而这些任务的优化依赖于Hive的元数据索引。而传统数据库通常有复杂的索引结构和查询优化机制。
数据查询语言:Hive使用类似SQL的HiveQL,而传统数据库使用标准SQL。
4. hive的内部表和外部表的区别
内部表数据由Hive自身管理,外部表数据由HDFS管理;
内部表数据存储的位置是hive.metastore.warehouse.dir(默认:/user/hive/warehouse),外部表数据的存储位置由自己制定(如果没有LOCATION,Hive将在HDFS上的/user/hive/warehouse文件夹下以外部表的表名创建一个文件夹,并将属于这个表的数据存放在这里);
删除内部表会直接删除元数据(metadata)及存储数据;删除外部表仅仅会删除元数据,HDFS上的文件并不会被删除。
5. hive静态分区和动态分区的区别
静态分区是指在加载数据时要指定分区值
sql
CREATE TABLE partitioned_table (name STRING, value INT) PARTITIONED BY (date STRING, country STRING);
INSERT INTO TABLE partitioned_table PARTITION (date='2020-01-01', country='US') VALUES ('A', 1);
INSERT INTO TABLE partitioned_table PARTITION (date='2020-01-01', country='CA') VALUES ('B', 2);
动态分区在加载数据的时候并不需要制定分区,hive会按照数据文件的路径自动识别分区
sql
SET hive.exec.dynamic.partition=true;
SET hive.exec.dynamic.partition.mode=nonstrict;
CREATE TABLE dynamic_partitioned_table (name STRING, value INT) PARTITIONED BY (date STRING, country STRING);
INSERT INTO TABLE dynamic_partitioned_table SELECT *, 'date', 'country' FROM source_table;
6. 内连接、左外连接、右外连接的区别
内连接
sql
SELECT *
FROM table1 t1
INNER JOIN table2 t2
ON t1.id = t2.id;
左外连接
sql
SELECT *
FROM table1 t1
LEFT OUTER JOIN table2 t2
ON t1.id = t2.id;
右外连接
sql
SELECT *
FROM table1 t1
LEFT OUTER JOIN table2 t2
ON t1.id = t2.id;
7. hive的join底层实现
底层是通过Map Reduce实现,在执行join操作的时候,map阶段会将数据分割成对应键值对,reduce阶段会按照这些键值对进行合并
大量数据的表要慎用join操作
8. Order By和Sort By的区别
在排序范围方面,后者用于对局部结果进行排序,但不保证全局有序;前者用于全局排序,更适合严格排序的场景
前者适用于数据量小且全局排序的情况,后者适用于数据量大分布式计算的情况。将大量数据使用前者进行排序操作很可能出现内存溢出的问题
9. 行转列和列转行函数
行转列
sql
-- 创建示例表
CREATE TABLE my_table(id INT, values ARRAY<STRING>);
-- 插入示例数据
INSERT INTO my_table VALUES (1, ['a', 'b', 'c']);
-- 行转列
SELECT id, value
FROM my_table
LATERAL VIEW explode(values) tbl AS value;
列转行
sql
-- 创建示例表
CREATE TABLE my_table(id INT, value1 STRING, value2 STRING, value3 STRING, value4 STRING);
-- 插入示例数据
INSERT INTO my_table VALUES (1, 'a', 'b', 'c', 'd');
-- 列转行
SELECT id, col_value
FROM my_table
LATERAL VIEW explode(array(value1, value2, value3, value4)) as tbl(col_value);
10. grouping_sets、cube和rollup
不同的分组聚合函数
11. 自定义过UDF、UDTF函数吗
用户自定义函数 用户自定义表生成函数
12. hive3的新特性有了解过吗
Vectorized Query Execution: 向量化查询执行提供了更快的性能,特别是对于数据处理密集型的操作。
Window Function Enhancements: 增强了对窗口函数的支持,包括对窗口指定的改进和更好的性能。
Hive Warehouse Connector (HWC): 提供了一种将 Spark 和 Hive 集成的新方式,可以更容易地在 Spark 应用程序中读写 Hive 表。
13. hive小文件过多怎么办
在数据加载到Hive表之前,先进行合适的文件合并。可以使用INSERT OVERWRITE语句将数据先插入到一个临时表,然后再从这个临时表中以合适的格式重新导出文件。
14. Hive优化
常见的有分区优化和分桶优化
分区优化:分区是将大数据集划分为更小、更易管理的部分的过程。Hive中的分区是指将表的数据分割成不同的目录来存储,每个分区都有自己的目录。优化分区可以通过减少全表扫描来提高查询效率。适合时间为单位
分桶优化:分桶是将数据集划分为更小的单位,每个单位都有一个固定的列和值范围。Hive中的分桶是通过对表进行散列来实现的,每个桶都存储了散列键值在一定范围内的数据。适合区域或者范围为单位
sql
-- 创建分区表
CREATE TABLE partitioned_table (id INT, value STRING)
PARTITIONED BY (year INT, month INT, day INT);
-- 插入数据时指定分区
INSERT OVERWRITE TABLE partitioned_table PARTITION (year=2021, month=10, day=1)
SELECT id, value FROM source_table WHERE year=2021 AND month=10 AND day=1;
-- 创建分桶表
CREATE TABLE bucketed_table (id INT, value STRING)
CLUSTERED BY (id) SORTED BY (value) INTO 32 BUCKETS;
-- 插入数据时分桶会自动进行
INSERT INTO bucketed_table SELECT id, value FROM source_table;
15. 常用函数的补充
数学函数:
round:对给定的数字进行四舍五入取近似值。例如:select round(3.1415926); 返回3。
floor:向下取整。例如:select floor(3.1415926); 返回3。
ceil:向上取整。例如:select ceil(3.1415926); 返回4。
rand:生成0到1之间的随机数。例如:select rand(); 返回一个随机数。
pow:进行幂运算。例如:select pow(2, 3); 返回8
字符串函数:
length:获取字符串长度。例如:select length('hello'); 返回5。
reverse:字符串反转。例如:select reverse('hello'); 返回olleh。
concat:字符串拼接。例如:select concat('hello', ' world'); 返回hello world。
substr:字符串截取。例如:select substr('hello world', 1, 5); 返回hello。
trim:去除字符串两端的空格。例如:select trim(' hello '); 返回hello。
upper、lower:字符串大小写转换。例如:select upper('hello'); 返回HELLO
日期函数:
current_date:获取当前日期。例如:select current_date(); 返回当前日期。
current_timestamp:获取当前时间戳。例如:select current_timestamp(); 返回当前时间戳。
unix_timestamp:将日期转换为UNIX时间戳。例如:select unix_timestamp('2023-01-01'); 返回对应的UNIX时间戳。
from_unixtime:将UNIX时间戳转换为日期格式。例如:select from_unixtime(1609459200); 返回对应的日期
条件函数:
if:条件判断函数。例如:select if(condition, value_if_true, value_if_false); 根据条件返回不同的值。
case:条件选择函数。例如:select case when condition then value_if_true else value_if_false end; 根据条件选择不同的值