天天看點

Hive分區(靜态分區+動态分區)

Hive分區的概念與傳統關系型資料庫分區不同。 傳統資料庫的分區方式:就oracle而言,分區獨立存在于段裡,裡面存儲真實的資料,在資料進行插入的時候自動配置設定分區。 Hive的分區方式:由于Hive實際是存儲在HDFS上的抽象,Hive的一個分區名對應一個目錄名,子分區名就是子目錄名,并不是一個實際字段。

是以可以這樣了解,當我們在插入資料的時候指定分區,其實就是建立一個目錄或者子目錄,或者在原有的目錄上添加資料檔案。

Hive分區是在建立表的時候用Partitioned by 關鍵字定義的,但要注意,Partitioned by子句中定義的列是表中正式的列,但是Hive下的資料檔案中并不包含這些列,因為它們是目錄名。

建立一張靜态分區表par_tab,單個分區

這時候通過desc檢視的表結構如下

準備本地資料檔案par_tab.txt,内容 “名字/國籍”,将以性别(sex)作為分區

把資料插入到表(其實load操作相當于把檔案移動到HDFS的Hive目錄下)

這時候在hive下查詢par_tab表,變成了3列,注意。

檢視par_tab目錄結構

可以看到,在建立分區表的時候,系統會在hive資料倉庫預設路徑/user/hive/warehouse/下建立一個目錄(表名),再建立目錄的子目錄sex=man(分區名),最後在分區名下存放實際的資料檔案。

如果再插入另一個資料檔案資料,如檔案

插入資料

檢視par_tab表目錄結構

最後檢視兩次插入的結果,包含了man和woman

因為分區列是表實際定義的列,是以查詢分區資料時

下面建立一張靜态分區表par_tab_muilt,多個分區(性别+日期)

可見,建立表的時候定義的分區順序,決定了檔案目錄順序(誰是父目錄誰是子目錄),正因為有了這個層級關系,當我們查詢所有man的時候,man以下的所有日期下的資料都會被查出來。如果隻查詢日期分區,但父目錄sex=man和sex=woman都有該日期的資料,那麼Hive會對輸入路徑進行修剪,進而隻掃描日期分區,性别分區不作過濾(即查詢結果包含了所有性别)。

如果用上述的靜态分區,插入的時候必須首先要知道有什麼分區類型,而且每個分區寫一個load data,太煩人。使用動态分區可解決以上問題,其可以根據查詢得到的資料動态配置設定到分區裡。其實動态分區與靜态分區差別就是不指定分區目錄,由系統自己選擇。

首先,啟動動态分區功能

假設已有一張表par_tab,前兩列是名稱name和國籍nation,後兩列是分區列,性别sex和日期dt,資料如下

現在我把這張表的内容直接插入到另一張表par_dnm中,并實作sex為靜态分區,dt動态分區(不指定到底是哪日,讓系統自己配置設定決定)

插入後看下目錄結構

再檢視分區數

證明動态分區成功。

注意,動态分區不允許主分區采用動态列而副分區采用靜态列,這樣将導緻所有的主分區都要建立副分區靜态列所定義的分區。

動态分區可以允許所有的分區列都是動态分區列,但是要首先設定一個參數hive.exec.dynamic.partition.mode :

它的預設值是strick,即不允許分區列全部是動态的,這是為了防止使用者有可能原意是隻在子分區内進行動态建分區,但是由于疏忽忘記為主分區列指定值了,這将導緻一個dml語句在短時間内建立大量的新的分區(對應大量新的檔案夾),對系統性能帶來影響。

是以我們要設定:

繼續閱讀