问题1:Hive一条Select语句,底层是如何读取HDFS文件的?
-
基本流程
- step1:根据表名到Hive元数据中,找到这个表对应的HDFS地址
- step2:将对应的HDFS地址目录中所有数据进行读取处理
-
==举个栗子1:普通表查询==
select * from tb_emp;
-
a. Hive会在MySQL元数据库中找到一张TBLS的表:这张表存储了Hive中每张表的信息
-
b. Hive会根据表名找到这张Hive表对应的SD_ID
[图片上传失败...(image-1be2f0-1658200618304)]
-
c. Hive会在MySQL元数据库中找到一张SDS的表:这张表存储了Hive表与HDFS的对应关系
-
d. Hive会根据表名对应的SD_ID在SDS中表中找到表对应的HDFS地址
[图片上传失败...(image-c16d96-1658200618304)]
-
e. Hive会读取这个目录下的所有文件
-
-
==举个栗子2:分区表查询==
select * from tb_emp_part where dept = 10; -- dept是分区字段
-
a. Hive会在MySQL元数据库中找到一张TBLS的表:这张表存储了Hive中每张表的信息
-
b. Hive发现这张表为分区表,并且做了分区过滤,就先从TBLS中读取表的TBL_ID
[图片上传失败...(image-848c94-1658200618304)]
-
c. Hive会在MySQL元数据库中找到一张PARTITIONS的表:这张表存储了Hive中每个表的每个分区的信息
-
d. Hive会根据TBL_ID,找到这张表的所有分区的信息
[图片上传失败...(image-391470-1658200618304)]
-
e. Hive根据这个表每个分区的名称进行过滤,获取需要过滤的分区的SD_ID
-
f. Hive根据这个SD_ID到SDS表中,获取这个分区在HDFS中对应的地址
[图片上传失败...(image-ea865a-1658200618304)]
-
问题2:有一张Hive表db_test.tb_test1,是一张普通表
-
表在HDFS中的目录
/user/hive/warehouse/db_test.db/tb_test1
-
如果我通过hdfs命令手动往这个表的目录中放一个文件
hdfs dfs -put 1.txt /user/hive/warehouse/db_test.db/tb_test1
-
请问表中select是否能读到这个文件的数据?
可以,根据Hive映射原理,Hive会直接读取这个表对应的HDFS目录,只要是目录下的文件都会被读取
问题3:有一张Hive表db_test.tb_test2,是一张分区表
-
表在HDFS中的目录结构
/user/hive/warehouse/db_test.db/tb_test2/daystr=2022-01-01/20220101.txt /daystr=2022-01-02/20220102.txt ……
-
问题:如果手动在HDFS的这个目录中创建一个分区的目录,然后将数据放入这个分区目录中
hdfs dfs -mkdir /user/hive/warehouse/db_test.db/tb_test2/daystr=2022-03-28 hdfs dfs -put 20220328.txt /user/hive/warehouse/db_test.db/tb_test2/daystr=2022-03-28
-
请问Hive中能否读到这个分区?
不能,因为根据分区表的元数据映射,这个分区目录必须在元数据中有才能被读到,而这个分区目录是用户自己创建的,Hive中没有对应的元数据所以,读取不到的
-
解决:手动添加这个分区的元数据
alter table tb_test2 add if not exists partition (daystr=2022-03-28);
网友评论