pypark hive 开启动态分区_Hive分区与分桶
分區、分桶的作用:
我們知道在傳統的DBMs系統中,一般都具有表分區的功能,通過表分區能夠在特定的區域檢索數據,減少掃描成本,在一定程度上提高了查詢效率,當然我們還可以通過進一步在分區上建立索引,進一步提高查詢效率。
在Hive中的數據倉庫中,也有分區分桶的概念,在邏輯上,分區表與未分區表沒有區別,在物理上分區表會將數據按照分區間的列值存儲在表目錄的子目錄中,目錄名=“分區鍵=鍵值”。其中需要注意的是分區鍵的列值存儲在表目錄的子目錄中,目錄名=“分區鍵=鍵值”。其中需要注意的是分區鍵的值不一定要基于表的某一列(字段),它可以指定任意值,只要查詢的時候指定相應的分區鍵來查詢即可。我們可以對分區進行添加、刪除、重命名、清空等操作。
分桶則是指定分桶表的某一列,讓該列數據按照哈希取模的方式隨機、均勻的分發到各個桶文件中。因為分桶操作需要根據某一列具體數據來進行哈希取模操作,故指定的分桶列必須基于表中的某一列(字段)。分桶改變了數據的存儲方式,它會把哈希取模相同或者在某一個區間的數據行放在同一個桶文件中。如此一來便可以提高查詢效率。如果我們需要對兩張在同一個列上進行了分桶操作的表進行JOIN操作的時候,只需要對保存相同列值的通進行JOIN操作即可。
還有一點需要點一下:在hive中的數據是存儲在hdfs中的,我們知道hdfs中的數據是不允許修改只能追加的,那么在hive中執行數據修改的命令時,就只能先找到對應的文件,讀取后執行修改操作,然后重新寫一份文件。如果文件比較大,就需要大量的IO讀寫。在hive中采用了分桶的策略,只需要找到文件存放對應的桶,然后讀取再修改寫入即可。
分區:
hive中分區分為 : 單值分區、范圍分區。
單值分區: 靜態分區 動態分區
如下所示,現在有一張persionrank表,記錄每個人的評級,有id、name、score字段。我們可以創建分區rank(rank不是表中的列,我們可以把它當做虛擬列),并將相應的數據導入指定分區(將數據插入指定目錄)。
單值分區:
單值靜態分區:導入數據時需要手動指定分區
單值動態分區:導入數據時,系統可以動態判斷目標分區
1.靜態分區創建:
直接在PARTITI1ONED BY后面跟上分區鍵、類型即可(指定的分區鍵不能出現在定義列名中)
CREATE [EXTERNAL] TABLE <table_name>(<col_name> <data_type> [, <col_name> <data_type> ...])-- 指定分區鍵和數據類型PARTITIONED BY (<partition_key> <data_type>, ...) [CLUSTERED BY ...] [ROW FORMAT <row_format>] [STORED AS TEXTFILE|ORC|CSVFILE][LOCATION '<file_path>'] [TBLPROPERTIES ('<property_name>'='<property_value>', ...)];2.靜態分區寫入:
-- 覆蓋寫入 INSERT OVERWRITE TABLE <table_name> PARTITION (<partition_key>=<partition_value>[, <partition_key>=<partition_value>, ...]) SELECT <select_statement>;-- 追加寫入 INSERT INTO TABLE <table_name> PARTITION (<partition_key>=<partition_value>[, <partition_key>=<partition_value>, ...])SELECT <select_statement>;3.添加分區:
//只能添加分區列的值,不能添加分區列,如果是多個分區列,不能單獨添加其中一個 alter table tablename add partition(col=value)4.刪除分區:
//可以刪除一個分區列,但是會把表中所有包含當前分區列的數據全部刪除 alter table tablename drop partition(col=value)5.修復分區:
//手動向hdfs中創建分區目錄,添加數據,創建好hive的外表之后,無法加載數據, //元數據中沒有相應的記錄 msck repair table tablename6.動態分區創建:
創建方式與靜態分區表完全一樣,一張表可同時被靜態分區和動態分區鍵分區,只是動態分區鍵需要放在靜態分區鍵的后面(HDFS上的動態分區目錄下不能包含靜態分區的子目錄),如下spk即static partition key(靜態分區鍵),dpk為dynamic partition key(動態分區鍵)
CREATE TABLE <table_name>PARTITIONED BY ([<spk> <data_type>, ... ,] <dpk> <data_type>, [<dpk> <data_type>,...]);7.動態分區寫入:
根據表中的某一個列值來確定hdfs存儲的目錄:
優點:
動態可變,不需要人為控制。假如設定的是日期,那么每一天的數據會單獨存儲在一個文件夾中
缺點:
需要依靠MR完成,執行比較慢
靜態分區鍵要用 <spk>=<value> 指定分區值;動態分區只需要給出分出分區鍵名稱 <dpk>。
-- 開啟動態分區支持,并設置最大分區數 set hive.exec.dynamic.partition=true; //set hive.exec.dynamic.partition.mode=nostrict; set hive.exec.max.dynamic.partitions=2000;insert into table1 select 普通字段 分區字段 from table2范圍分區:
單值分區每個分區對應于分區鍵的一個取值,而每個范圍分區則對應分區鍵的一個區間,只要落在指定區間內的記錄都被存儲在對應的分區下。分區范圍需要手動指定,分區的范圍為前閉后開區間 [最小值, 最大值)。最后出現的分區可以使用 MAXVALUE 作為上限,MAXVALUE 代表該分區鍵的數據類型所允許的最大值。
CREATE [EXTERNAL] TABLE <table_name>(<col_name> <data_type>, <col_name> <data_type>, ...)PARTITIONED BY RANGE (<partition_key> <data_type>, ...) (PARTITION [<partition_name>] VALUES LESS THAN (<cutoff>), [PARTITION [<partition_name>] VALUES LESS THAN (<cutoff>),...]PARTITION [<partition_name>] VALUES LESS THAN (<cutoff>|MAXVALUE) )[ROW FORMAT <row_format>] [STORED AS TEXTFILE|ORC|CSVFILE][LOCATION '<file_path>'] [TBLPROPERTIES ('<property_name>'='<property_value>', ...)];多個范圍分區鍵的情況:
DROP TABLE IF EXISTS test_demo; CREATE TABLE test_demo (value INT) PARTITIONED BY RANGE (id1 INT, id2 INT, id3 INT) ( -- id1在(--∞,5]之間,id2在(-∞,105]之間,id3在(-∞,205]之間 PARTITION p5_105_205 VALUES LESS THAN (5, 105, 205), -- id1在(--∞,5]之間,id2在(-∞,105]之間,id3在(205,215]之間 PARTITION p5_105_215 VALUES LESS THAN (5, 105, 215), PARTITION p5_115_max VALUES LESS THAN (5, 115, MAXVALUE), PARTITION p10_115_205 VALUES LESS THAN (10, 115, 205), PARTITION p10_115_215 VALUES LESS THAN (10, 115, 215), PARTITION pall_max values less than (MAXVALUE, MAXVALUE, MAXVALUE) );分桶:
對Hive(Inceptor)表分桶可以將表中記錄按分桶鍵的哈希值分散進多個文件中,這些小文件稱為桶。
1.創建分桶表:
分桶表的建表有三種方式:直接建表,CREATE TABLE LIKE 和 CREATE TABLE AS SELECT ,單值分區表不能用 CREATE TABLE AS SELECT 建表。這里以直接建表為例:
CREATE [EXTERNAL] TABLE <table_name>(<col_name> <data_type> [, <col_name> <data_type> ...])][PARTITIONED BY ...] CLUSTERED BY (<col_name>) [SORTED BY (<col_name> [ASC|DESC] [, <col_name> [ASC|DESC]...])] INTO <num_buckets> BUCKETS [ROW FORMAT <row_format>] [STORED AS TEXTFILE|ORC|CSVFILE][LOCATION '<file_path>'] [TBLPROPERTIES ('<property_name>'='<property_value>', ...)];分桶鍵只能有一個即<col_name>。表可以同時分區和分桶,當表分區時,每個分區下都會有<num_buckets> 個桶。我們也可以選擇使用 SORTED BY … 在桶內排序,排序鍵和分桶鍵無需相同。ASC 為升序選項,DESC 為降序選項,默認排序方式是升序。<num_buckets> 指定分桶個數,也就是表目錄下小文件的個數。
2.向分桶表中寫數據:
因為分桶表在創建的時候只會定義Scheme,且寫入數據的時候不會自動進行分桶、排序,需要人工先進行分桶、排序后再寫入數據。確保目標表中的數據和它定義的分布一致。
目前有兩種方式往分桶表中插入數據:
方法一:打開enforce bucketing開關。
SET hive.enforce.bucketing=true; INSERT (INTO|OVERWRITE) TABLE <bucketed_table> SELECT <select_statement> [SORT BY <sort_key> [ASC|DESC], [<sort_key> [ASC|DESC], ...]];方法二:將reducer個數設置為目標表的桶數,并在 SELECT 語句中用 DISTRIBUTE BY <bucket_key>對查詢結果按目標表的分桶鍵分進reducer中。
SET mapred.reduce.tasks = <num_buckets>; INSERT (INTO|OVERWRITE) TABLE <bucketed_table> SELECT <select_statement> DISTRIBUTE BY <bucket_key>, [<bucket_key>, ...] [SORT BY <sort_key> [ASC|DESC], [<sort_key> [ASC|DESC], ...]];如果分桶表創建時定義了排序鍵,那么數據不僅要分桶,還要排序
如果分桶鍵和排序鍵不同,且按降序排列,使用Distribute by … Sort by分桶排序
如果分桶鍵和排序鍵相同,且按升序排列(默認),使用 Cluster by 分桶排序,即如下:
SET mapred.reduce.tasks = <num_buckets>; INSERT (INTO|OVERWRITE) TABLE <bucketed_table> SELECT <select_statement> CLUSTER BY <bucket_sort_key>, [<bucket_sort_key>, ...];抽樣語句 :tablesample(bucket x out of y)
tablesample是抽樣語句,語法:tablesample(bucket x out of y),y必須是table總共bucket數的倍數或者因子。Hive根據y的大小,決定抽樣的比例。例如:table總共分了64份,當y=32時,抽取2(64/32)個bucket的數據,當y=128時,抽取1/2(64/128)個bucket的數據。x表示從哪個bucket開始抽取。例如:table總共bucket數為32,tablesample(bucket 3 out of 16)表示總共抽取2(32/16)個bucket的數據,分別為第三個bucket和第19(3+16)個bucket的數據。
總結
以上是生活随笔為你收集整理的pypark hive 开启动态分区_Hive分区与分桶的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: css使两个盒子并列_css如何去掉重叠
- 下一篇: mysql count null_MyS