03.03 Hive分區表

一:簡介

分區表就是根據指定字段的值進行分類、分組,字段值相同的分為一類然後存儲在一個單獨的HDFS文件中,多個類就存儲在多個文件中。原本存儲在一個文件中的數據現在存儲在多個文件中,查詢數據時只需要知道數據在哪個類別中然後直接去對應類對應的文件中去查詢就好,這樣只需掃描這一個類別的文件而不需要掃描所有文件,這樣提高了查詢效率。

分區表就是對文件進行水平分割,對數據分門別類的分開存儲。

分區表有兩種:

  • 靜態分區: 必須手動顯式的添加需要分區的字段值, 分類的值有多少個就要添加多少次 (alter table add partition)。靜態分區適合分區字段的值比較少的情況。
  • 動態分區:創建表時只需指定要分區的字段名即可,不需要指定分區字段有哪些具體的值。動態分區適用於字段值相對比較多的情況。

二:靜態分區

1. 創建表並通過partitioned by指定分區字段

分區字段和普通字段是一樣的,需要指定 [comment '字段註釋'],分區字段也會作為表的列。

<code>hive> create database test;

hive> use test;

hive> create table tbl_user (id bigint,username string comment '用戶名')
partitioned by (country string comment '國家', state string comment '地區')
row format delimited
fields terminated by ","
lines terminated by "\\n"
stored as textfile;
/<code>

查看錶結構

<code>hive> describe extended tbl_user;
hive> desc tbl_user;
/<code>

創建表後HDFS:/data/hive/warehouse/test.db/

Hive分區表

2. 添加分區
<code>>hive alter table tbl_user add  partition (country="China",state="Asia");
>hive alter table tbl_user add partition (country="Japan",state="Asia");

-- 顯示分區
>hive show partitions tbl_user;

-- 刪除分區
alter table tbl_user drop partition(country="China",state="Asia")
/<code>

添加分區後hdfs中會有對應的分區目錄,如果是多個分區則會具體再分出子目錄。

Hive分區表

Hive分區表

3. 插入數據
<code>echo "1,zhangsan,China,Asia\\n2,lisi,China,Asia" >  '/tmp/china.txt' 
echo "3,wangwu,Japan,Asia\\n4,liuliu,Japan,Asia" > '/tmp/japan.txt'

hive> load data local inpath '/tmp/china.txt' into table tbl_user partition (country = 'China', state= 'Asia');
hive> load data local inpath '/tmp/japan.txt' into table tbl_user partition (country = 'Japan', state= 'Asia');

-- 查詢時使用分區字段作為條件加快查詢速度
>hive select * from tbl_user where country='Japan';
/<code>
Hive分區表

三: 動態分區

動態分區默認是沒有開啟的,開啟後默認是嚴格模式即至少有一個靜態分區,也可以關閉嚴格模式。

1. 關閉嚴格分區模式

關閉嚴格模式可以在hive-site.xml文件中配置,也可以通過命令行臨時配置。

<code><property>
<name>hive.exec.dynamic.partition/<name>
<value>true/<value>
/<property>

<property>
<name>hive.exec.dynamic.partition.mode/<name>
<value>nonstrict/<value>
/<property>

<property>
<name>hive.exec.max.dynamic.partitions/<name>
<value>1000/<value>
/<property>
/<code>
<code>-- 非嚴格模式
hive> set hive.exec.dynamic.partition.mode=nonstrict;
-- 開啟動態分區
hive> set hive.exec.dynamic.partition=true;
-- 最大動態分區數,默認1000
hive> set hive.exec.max.dynamic.partitions=99999;
/<code>
2. 創建表

動態分區創建表和靜態分區創建表是一樣的,只需要指定需要分區的字段,分區字段可以是多個。

<code>create table tbl_user_dy (id bigint,username string)
partitioned by (city string)
row format delimited
fields terminated by ","
lines terminated by "\\n"
stored as textfile;
/<code>
Hive分區表

3. 插入數據
<code>echo "1,zhangsan,shanghai\\n2,lisi,beijing\\n3,wangwu,shenzhen\\n4,liuliu,shanghai" > '/tmp/user.txt' 
/<code>

注意:動態分區不能使用load data local inpath '/tmp/user.txt' into table tbl_user_dy partition(city);進行加載數據, 否則會報FAILED: NullPointerException null。解決辦法是 先創建沒有分區的表,將數據加載到沒有分區的表,然後再將數據轉移到動態分區表。

創建臨時表不需要指定分區字段,將分區字段作為普通字段。

<code>hive> create table tbl_user_tmp (id bigint,username string, city string)
row format delimited
fields terminated by ","
lines terminated by "\\n"
stored as textfile;

-- 將數據加載到臨時表中
hive> load data local inpath '/tmp/user.txt' into table tbl_user_tmp;

-- 將臨時表中的數據插入到動態分區表中
hive> insert into table tbl_user_dy partition(city) select * from tbl_user_tmp;
/<code>

自動分區會自動根據分區字段的值進行分區,這裡根據城市city動態分區的,不需要手動顯式添加分區值。

Hive分區表

Hive分區表


分享到:


相關文章: