1. 程式人生 > >hive分割槽partition(動態和靜態分割槽混合使用; partition的簡介)

hive分割槽partition(動態和靜態分割槽混合使用; partition的簡介)

分割槽是hive存放資料的一種方式。將列值作為目錄來存放資料,就是一個分割槽。這樣where中給出列值時,只需根據列值直接掃描對應目錄下的資料,不掃面其他不關心的分割槽,快速定位,查詢節省大量時間。分動態和靜態分割槽兩種

動態分割槽

1)不顯示的給出分割槽名,根據列的取值自動建立對應分割槽(多少種取值,多少種分割槽),所以需要限制最大分割槽數:
    SET hive.exec.dynamic.partition=true;
    SET hive.exec.max.dynamic.partitions.pernode=1000;
    SET hive.exec.max.dynamic.partitions=3000; 
2)分割槽全部使用動態分割槽,還要設定為nonstrict模式,否則無法執行
    set hive.exec.dynamic.partition.mode=nonstrict;

3)動態分割槽按位置來對應,跟名稱無關。所以查詢select中必須在最後欄位按動態分割槽順序給出對應欄位
    insert overwrite table tb_pmp_raw_log_analysis_count partition (day='2016-05-17', media,type)
        select advertiser_id,ad_plan_id,crt_id,hour,ad_place_id,city_bidrequest,device,network,os,category,channel,ad_type,rtb_type,price,count(1) as cnt,media, 1 as type
        from (
          select
split(all,'\\\\|~\\\\|')[41] as advertiser_id, split(all,'\\\\|~\\\\|')[10] as ad_plan_id, split(all,'\\\\|~\\\\|')[11] as crt_id, substr(split(all,'\\\\|~\\\\|')[0],12,2) as hour, case when split(split(all,'\\\\|~\\\\|')[5],'/'
)[1] = 'wax' then split(all,'\\\\|~\\\\|')[17] else split(all,'\\\\|~\\\\|')[7] end as city_bidrequest, NULL as device, NULL as network, NULL as os, NULL as category, NULL as channel, NULL as ad_type, NULL as rtb_type, split(all,'\\|~\\|')[13] as price, split(split(all,'\\\\|~\\\\|')[5],'/')[1] as media from tb_pmp_raw_log_bid_tmp tb ) a group by advertiser_id,ad_plan_id,crt_id,hour,ad_place_id,city_bidrequest,device,network,os,category,channel,ad_type,rtb_type,price,media distribute by media;
注意:動態分割槽名稱無關,順序必須一致

4)distribute by 和動態分割槽原理一樣,一般不一起用,如程式碼

5)動態分割槽與靜態分割槽混用:
    a) 只要有一個靜態分割槽,就可以在預設的strict狀態執行。如上程式碼,動靜分割槽混用時,不用設定nonstrict狀態。
    b) 動態分割槽不能在靜態分割槽前面,在select中按位置順序出現在最後(因為靜態分割槽提前產生,動態分割槽執行時產生,如果動態分割槽作為父路徑,則子靜態分割槽無法提前生成。會報錯為動態分割槽不能為靜態的父路徑)。程式碼中,type設為靜態,但media是動態,會報錯,所以才在內部給定type的值。如果分割槽順序改為day、type、media,則可以將day和type作為靜態,media做動態。

Hive partition 匯出時無名稱:

存在分割槽partition的hive表,用select *返回包括分割槽欄位值。
但select * >localdata.txt匯入本地檔案,無分割槽欄位名稱,但值記錄存在。也就是說,檔案中第一行的屬性欄位中無分割槽欄位屬性,而分割槽屬性的取值在記錄中存在。
如果要匯入資料到mysql裡,或用kettle讀入時,記得要手動加上分割槽列對應的屬性列名稱

Hive partition 簡介

在HiveSelect查詢中一般會掃描整個表內容,會消耗很多時間做沒必要的工作。有時候只需要掃描表中關心的一部分資料,因此引入了partition概念。建表時指定partition空間。一個Partition對應於表下的一個目錄,所有的Partition的資料都儲存在自己的目錄。
總的說來partition就是輔助查詢,縮小查詢範圍,加快資料的檢索速度和對資料按照一定的規格和條件進行管理。

Partition的使用:

檢視分割槽:show partitions hive_tb;
1、分割槽以欄位形式在表結構中存在,通過describetable命令可以檢視分割槽欄位,但該欄位不存放實際的資料內容,僅僅是分割槽的表示。
2、可有多個分割槽,每個分割槽以資料夾的形式單獨存在表文件夾的目錄下。
3、分割槽建表分為2種,一種是單分割槽,在表文件夾目錄下只有一級資料夾目錄。另外一種是多分割槽,表文件夾下多資料夾巢狀模
a、單分割槽建表語句:createtable day_table (id int, content string) partitioned by (dt string);單分割槽表,按天分割槽,在表結構中存在id,content,dt三列。
b、雙分割槽建表語句:createtable day_hour_table (id int, content string) partitioned by (dt string, hourstring);雙分割槽表,按天和小時分割槽,在表結構中新增加了dt和hour兩列。

Hive partition基本語法:

1.建立分割槽表語法:
CREATE [EXTERNAL] TABLE [IF NOT EXISTS] table_name [(col_namedata_type [COMMENT col_comment], ...)] [COMMENT table_comment] [PARTITIONED BY(col_name data_type [COMMENT col_comment], ...)] [CLUSTERED BY (col_name,col_name, ...) [SORTED BY (col_name [ASC|DESC], ...)] INTO num_buckets BUCKETS][ROW FORMAT row_format] [STORED AS file_format] [LOCATION hdfs_path]
雙分割槽表,按天和小時分割槽,在表結構中新增加了dt和hour兩列。
create table day_hour_table (id int, content string)partitioned by (dt string, hour string);
2.新增分割槽表語法(表已建立,在此基礎上新增分割槽):
ALTERTABLE table_name ADD partition_spec [ LOCATION 'location1' ] partition_spec [LOCATION 'location2' ] ... partition_spec: : PARTITION (partition_col =partition_col_value, partition_col = partiton_col_value, ...)
向一個表中增加分割槽(ALTER TABLE ADDPARTITION)。當分割槽名是字串時加引號。例:
ALTERTABLE day_table ADD PARTITION (dt='2008-08-08', hour='08') location'/path/pv1.txt' PARTITION (dt='2008-08-08', hour='09') location'/path/pv2.txt';
3.刪除分割槽(ALTER TABLE table_name DROP partition_spec,partition_spec,…)分割槽的元資料和資料將被一併刪除,例:
ALTERTABLE day_hour_table DROP PARTITION (dt='2008-08-08', hour='09');
4.分割槽表載入資料語法:
LOADDATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE tablename [PARTITION(partcol1=val1, partcol2=val2 ...)]

例:

LOADDATA INPATH '/user/pv.txt' INTO TABLE day_hour_table PARTITION(dt='2008-08-08', hour='08'); LOAD DATA local INPATH '/user/hua/*' INTO TABLE day_hourpartition(dt='2010-07- 07');
資料載入至表中,不會對資料進行任何轉換。Load操作只是將資料複製至Hive表對應的位置。資料載入時自動在表下建立一個目錄,檔案存放在該分割槽下。
5.基於分割槽的查詢的語句:
SELECTday_table.* FROM day_table WHERE day_table.dt>= '2008-08-08';
6. 檢視分割槽:
show partitions 表名;  
show partitions hive_tb;

hive中partition的實際操作:

hive>create table mp (a string) partitioned by (b string, c string);
hive> alter table mp add partition (b='1', c='1');
hive> alter table mp add partition (b='1', c='2');
hive> alter table mp add partition (b='2', c='2');
hive> show partitions mp ;

b=1/c=1
b=1/c=2
b=2/c=2

hive>explain extended alter table mp drop partition (b='1');

ABSTRACTSYNTAX TREE:
(TOK_ALTERTABLE_DROPPARTS mp (TOK_PARTSPEC (TOK_PARTVAL b '1')))
STAGEDEPENDENCIES:
Stage-0 is a root stage
STAGEPLANS:
Stage: Stage-0
Drop Table Operator:
Drop Table
table: mp

hive> alter table mp drop partition (b='1');
FAILED: Error in metadata: table is partitioned but partition spec is notspecified or tab: {b=1}
FAILED: Execution Error, return code 1 fromorg.apache.hadoop.hive.ql.exec.DDLTask
hive> show partitions mp ;

b=1/c=1
b=1/c=2
b=2/c=2

hive>alter table mp add partition ( b='1', c = '3') partition ( b='1' , c='4');
hive> show partitions mp ;
b=1/c=1
b=1/c=2
b=1/c=3
b=1/c=4
b=2/c=2
b=2/c=3

hive>insertoverwrite table mp partition (b='1', c='1') select cnt from tmp_et3 ;
hive>altertable mp add columns (newcol string);
location指定目錄結構:
alter table wizad_mdm_raw_hdfs add partition (day='2014-11-07',adn='3') location '/user/wizad/data/wizad/raw/2014-11-07/3_1/';
hive>alter table alter2 add partition (insertdate='2008-01-01') location'2008/01/01';
hive>alter table alter2 add partition (insertdate='2008-01-02') location'2008/01/02';