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;)
- 臨時表(建立表時新增TEMPORARY關鍵字)和永久表
- 內部表&外部表
a) 刪除內部表時,表結構(元資訊)和表對應的資料會一同被刪除
b) 刪除外部表時,只有表結構被刪除
注意:建立表時如果指定了表的位置,建議表的型別是external
- 分割槽表
表內的資料按照地域、時間等業務緯度,在表內將資料進一步細分成分割槽。
- 分桶表
在分割槽表的基礎上,將分割槽內的資料進一步細分成桶。
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可能給出部分有序的結果。