前言
Hive的分區(qū)和分桶都是細化數(shù)據(jù)管理,加快數(shù)據(jù)查詢和分析,兩者有什么區(qū)別呢?下面講解一下分區(qū)和分桶的原理。
分區(qū)及原理
Hive的分區(qū)表可以有一個或多個分區(qū)鍵,用于確定數(shù)據(jù)的存儲方式。分區(qū)(除了作為存儲單元)還允許用戶有效地識別滿足指定條件的數(shù)據(jù),顯著加快查詢分析速度。分區(qū)字段并不是數(shù)據(jù)的一部分,而是加載時虛擬的列,數(shù)據(jù)在HDFS上存儲時分區(qū)就相當于文件目錄。
分區(qū)建表SQL
分區(qū)表使用partitioned by 子句指定,以指定字段列,需要指定字段類型。
--分區(qū)表建表sql
USE testdb;
CREATE TABLE test_partition (
field1 String Comment 'field1 comment',
field2 String Comment 'field2 comment')
Comment 'table comment'
PARTITIONED BY(d String Comment 'date')
STORED AS ORC;
--分區(qū)表查詢
SELECT *
FROM testdb.test_partition
WHERE d = '2022-02-01'
建表完成后查看LOCATION參數(shù)為:'
hdfs://ns/user/hive/warehouse/testdb.db/test_partition'。當存儲數(shù)據(jù)時,2022-02-01日期的數(shù)存儲在hdfs://ns/user/hive/warehouse/testdb.db/test_partition/d=2022-02-01目錄下。
如果指定多個分區(qū)列用逗號分隔開,如:建表是PARTITIONED BY(d String Comment 'date',h String Comment 'hour'),分區(qū)字段日期常用格式:d=yyyy-MM-dd,h=HH。第二個參數(shù)會作為子目錄存儲在HDFS上:***/test_partition/d=2022-02-01/h=12
分桶及原理
分桶表中的數(shù)據(jù)可以根據(jù)表中某列的哈希函數(shù)的值依次劃分為存儲桶,用于分桶的字段是數(shù)據(jù)中實際的一列。其原理:根據(jù)分桶的列計算hash值,對hash值取模運算,將數(shù)據(jù)放到對應的桶里。
分桶建表SQL
分桶表由clustered by 子句指定,指定字段為真實字段,需要指定桶的個數(shù),桶編號從零開始。
--分桶表建表sql,創(chuàng)建4個桶
USE testdb;
CREATE TABLE test_bucket (
field1 String Comment 'field1 comment',
field2 String Comment 'field2 comment')
COMMENT 'table comment'
clustered by (field1) into 4 buckets
row format delimited
fields terminated by ',';
--分桶表查詢
SELECT *
FROM testdb.test_bucket
WHERE field1 = '0'
相同點和不同點
相同點:分區(qū)和分桶表都是Hive細化數(shù)據(jù)管理,加快數(shù)據(jù)查詢和分析。
不同點:
- 分區(qū)字段不是實際的列,分桶字段必須是實際的列。
- 分區(qū)表的分區(qū)數(shù)量可以一直增長,而分桶表創(chuàng)建好后桶的數(shù)量就固定不變了。
思考
因為分桶原理是用hash計算后取模計算分桶,用哈希計算必然會沖突,如果大批量數(shù)據(jù)計算的hash值相等,極端情況下全部數(shù)據(jù)集中到一個桶中時,就導致分桶表退化成一張維表。