問題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:分區(qū)表查詢==
select * from tb_emp_part where dept = 10; -- dept是分區(qū)字段a. Hive會在MySQL元數據庫中找到一張TBLS的表:這張表存儲了Hive中每張表的信息
-
b. Hive發(fā)現這張表為分區(qū)表,并且做了分區(qū)過濾,就先從TBLS中讀取表的TBL_ID
[圖片上傳失敗...(image-848c94-1658200618304)]
c. Hive會在MySQL元數據庫中找到一張PARTITIONS的表:這張表存儲了Hive中每個表的每個分區(qū)的信息
-
d. Hive會根據TBL_ID,找到這張表的所有分區(qū)的信息
[圖片上傳失敗...(image-391470-1658200618304)]
e. Hive根據這個表每個分區(qū)的名稱進行過濾,獲取需要過濾的分區(qū)的SD_ID
-
f. Hive根據這個SD_ID到SDS表中,獲取這個分區(qū)在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,是一張分區(qū)表
-
表在HDFS中的目錄結構
/user/hive/warehouse/db_test.db/tb_test2/daystr=2022-01-01/20220101.txt /daystr=2022-01-02/20220102.txt …… -
問題:如果手動在HDFS的這個目錄中創(chuàng)建一個分區(qū)的目錄,然后將數據放入這個分區(qū)目錄中
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中能否讀到這個分區(qū)?
不能,因為根據分區(qū)表的元數據映射,這個分區(qū)目錄必須在元數據中有才能被讀到,而這個分區(qū)目錄是用戶自己創(chuàng)建的,Hive中沒有對應的元數據所以,讀取不到的 -
解決:手動添加這個分區(qū)的元數據
alter table tb_test2 add if not exists partition (daystr=2022-03-28);