数据仓库-hive分区表
什么是分區
在邏輯上分區表與未分區表沒有區別,在物理上分區表會將數據按照分區鍵的列值存儲在表目錄的子目錄中,目錄名=“分區鍵=鍵值”。其中需要注意的是分區鍵的值不一定要基于表的某一列(字段),它可以指定任意值,只要查詢的時候指定相應的分區鍵來查詢即可。我們可以對分區進行添加、刪除、重命名、清空等操作。因為分區在特定的區域(子目錄)下檢索數據,它作用同DNMS分區一樣,都是為了減少掃描成本。
Hive(Inceptor)分區又分為單值分區、范圍分區。單值分區又分為靜態分區和動態分區。我們先看下分區長啥樣。如下,假如有一張表名為persionrank表,記錄每個人的評級,有id、name、score字段。我們便可以創建分區rank(注意rank不是表中的列,我們可以把它當做虛擬列),并將相應數據導入指定分區(將數據插入指定目錄)。
?
分區的好處
分區的種類
1、靜態分區
單分區
create table t1(id int,name string,hobby array<string>,add map<String,string> ) partitioned by (pt_d string) row format delimited fields terminated by ',' collection items terminated by '-' map keys terminated by ':' ;?注:這里分區字段不能和表中的字段重復。
如果分區字段和表中字段相同的話,會報錯,如下:
create table t1(id int,name string,hobby array<string>,add map<String,string> ) partitioned by (id int) row format delimited fields terminated by ',' collection items terminated by '-' map keys terminated by ':' ;報錯信息:FAILED: SemanticException [Error 10035]: Column repeated in partitioning columns
裝載數據
1,xiaoming,book-TV-code,beijing:chaoyang-shagnhai:pudong 2,lilei,book-code,nanjing:jiangning-taiwan:taibei 3,lihua,music-book,heilongjiang:haerbin執行load data
load data local inpath '/home/hadoop/Desktop/data' overwrite into table t1 partition ( pt_d = '201701');查看數據 select * from t1;
1 xiaoming ["book","TV","code"] {"beijing":"chaoyang","shagnhai":"pudong"} 201701 2 lilei ["book","code"] {"nanjing":"jiangning","taiwan":"taibei"} 201701 3 lihua ["music","book"] {"heilongjiang":"haerbin"} 201701給t1添加分區
alter table t1 add partition (pt_d ='00000');重新加載一份新的數據?
load data local inpath '/home/hadoop/Desktop/data' overwrite into table t1 partition ( pt_d = '000000');查看數據:select * from t1;
1 xiaoming ["book","TV","code"] {"beijing":"chaoyang","shagnhai":"pudong"} 000000 2 lilei ["book","code"] {"nanjing":"jiangning","taiwan":"taibei"} 000000 3 lihua ["music","book"] {"heilongjiang":"haerbin"} 000000 1 xiaoming ["book","TV","code"] {"beijing":"chaoyang","shagnhai":"pudong"} 201701 2 lilei ["book","code"] {"nanjing":"jiangning","taiwan":"taibei"} 201701 3 lihua ["music","book"] {"heilongjiang":"haerbin"} 201701可以查詢單個分區
select * from t1 where pt_d = ‘000000’多個分區
create table t10(id int,name string,hobby array<string>,add map<String,string> ) partitioned by (pt_d string,sex string) row format delimited fields terminated by ',' collection items terminated by '-' map keys terminated by ':' ;裝載數據(分區字段必須都要加)
load data local inpath ‘/home/hadoop/Desktop/data’ overwrite into table t10 partition ( pt_d = ‘0’);如果只是添加一個,會報錯:FAILED: SemanticException [Error 10006]: Line 1:88 Partition not found ”0”
load data local inpath '/home/hadoop/Desktop/data' overwrite into table t10 partition ( pt_d = '0',sex='male'); load data local inpath '/home/hadoop/Desktop/data' overwrite into table t10 partition ( pt_d = '0',sex='female');觀察HDFS上的文件,可發現多個分區具有順序性,可以理解為windows的樹狀文件夾結構。
?
?
?
2、動態分區
如果用上述的靜態分區,插入的時候必須首先要知道有什么分區類型,而且每個分區寫一個load data,太煩人。使用動態分區可解決以上問題,其可以根據查詢得到的數據動態分配到分區里。其實動態分區與靜態分區區別就是不指定分區目錄,由系統自己選擇。
首先啟動分區功能
hive> set hive.exec.dynamic.partition=true;假設已有一張表par_tab,前兩列是名稱name和國籍nation,后兩列是分區列,性別sex和日期dt,數據如下:
create table par_dam( name string, nation string, )partitioned by (sex string,date string)并加載數據?
select * from par_tab;OK lily china man 2013-03-28 nancy china man 2013-03-28 hanmeimei america man 2013-03-28 jan china man 2013-03-29 mary america man 2013-03-29 lilei china man 2013-03-29 heyong china man 2013-03-29 yiku japan man 2013-03-29 emoji japan man 2013-03-29 Time taken: 1.141 seconds, Fetched: 9 row(s)現在我把這張表的內容直接插入到另一張表par_dnm中,并實現sex為靜態分區,dt動態分區(不指定到底是哪日,讓系統自己分配決定)
create table par_dam( name string, nation string, )partitioned by (sex string,date string) insert overwrite table par_dnm partition(sex='man',dt) select name, nation, dt from par_tab;插入后看下目錄結構
?
drwxr-xr-x - hadoop supergroup 0 2017-03-29 10:32 /user/hive/warehouse/par_dnm/sex=man drwxr-xr-x - hadoop supergroup 0 2017-03-29 10:32 /user/hive/warehouse/par_dnm/sex=man/dt=2013-03-28 -rwxr-xr-x 1 hadoop supergroup 41 2017-03-29 10:32 /user/hive/warehouse/par_dnm/sex=man/dt=2013-03-28/000000_0 drwxr-xr-x - hadoop supergroup 0 2017-03-29 10:32 /user/hive/warehouse/par_dnm/sex=man/dt=2013-03-29 -rwxr-xr-x 1 hadoop supergroup 71 2017-03-29 10:32 /user/hive/warehouse/par_dnm/sex=man/dt=2013-03-29/000000_0再查看分區數
show partitions par_dnm;OK sex=man/dt=2013-03-28 sex=man/dt=2013-03-29 Time taken: 0.065 seconds, Fetched: 2 row(s)?
證明動態分區成功。
動態分區不允許主分區采用動態列而副分區采用靜態列,這樣將導致所有的主分區都要創建副分區靜態列所定義的分區。
動態分區可以允許所有的分區列都是動態分區列,但是要首先設置一個參數hive.exec.dynamic.partition.mode :
set hive.exec.dynamic.partition.mode;它的默認值是strick,即不允許分區列全部是動態的,這是為了防止用戶有可能原意是只在子分區內進行動態建分區,但是由于疏忽忘記為主分區列指定值了,這將導致一個dml語句在短時間內創建大量的新的分區(對應大量新的文件夾),對系統性能帶來影響。所以我們要設置:
set hive.exec.dynamic.partition.mode=nostrick;現在我把這張表的內容直接插入到另一張表par_dnm中,并實現sex為靜態分區,dt動態分區(不指定到底是哪日,讓系統自己分配決定)
insert overwrite table par_dnm partition(sex,dt) select name,nation,sex,dt from par_tab;?
?
表分區的增刪修查
1、增加分區
一次增加一個分區
alter table testljb add partition (age=2);?
一次增加多個分區
alter table testljb add partition(age=3) partition(age=4);?
注意:一定不能寫成如下方式:
alter table testljb add partition(age=5,age=6);?
如果我們show partitions table_name 會發現僅僅添加了age=6的分區。
???
有個表具有兩個分區字段:age分區和sex分區。那么我們添加一個age分區為1,sex分區為male的數據,可以這樣添加:
alter table testljb add partition(age=1,sex='male');?
2、刪除分區
刪除分區age=1
alter table testljb drop partition(age=1);?
3、修復分區
修復分區就是重新同步hdfs上的分區信息。
msck repair table table_name;?
4、查詢分區?
show partitions table_name;?
總結
以上是生活随笔為你收集整理的数据仓库-hive分区表的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一种无法用言语表达的爱——父爱
- 下一篇: [系统与控制]力场盾系统升级原因