Hive Partitioning

2021-04-08  本文已影响0人  watermark

Hive 分区是一项特别强大的功能,通过分区可以将一个表划分为更多的 pieces(实际上一个分区物理上对应 HDFS 一个目录),从而可以以更细的粒度对数据进行管理和访问。

分区的优点如下:

分区的种类

分区可以进一步分为 静态分区动态分区

分区表的创建语法:

CREATE [TEMPORARY] [EXTERNAL] TABLE [IF NOT EXISTS] 
  [db_name.]table_name
  [(col_name data_type [column_constraint_specification] [COMMENT col_comment],
  [COMMENT table_comment]
  [PARTITIONED BY (col_name data_type [COMMENT col_comment], ...)];

静态分区

静态分区需要明确指定向哪个分区写入。静态分区是可以 alter 的。
使用静态分区特性需要在 hive-site.xml 中设置属性 hive. mapred.mode = strict
通过以下例子感受一下静态分区。

CREATE TABLE user_data (
user_id INT,
user_name string,
site_data string
) PARTITIONED BY (
date_dt string,
country string
);
create-table.png
INSERT INTO TABLE user_data PARTITION(date_dt='2016-05-29', country='US') VALUES(201, 'Wick', 'Google');
INSERT INTO TABLE user_data PARTITION(date_dt='2016-05-20', country='UK') VALUES(202, 'John', 'Facebook');
INSERT INTO TABLE user_data PARTITION(date_dt='2016-05-20', country='UK') VALUES(203, 'Partick', 'Instagram');
INSERT INTO TABLE user_data PARTITION(date_dt='2016-05-29', country='UK') VALUES(204, 'Hema', 'Google');
INSERT INTO TABLE user_data PARTITION(date_dt='2016-05-28', country='INDIA') VALUES(205, 'Holi', 'Facebook');
INSERT INTO TABLE user_data PARTITION(date_dt='2016-05-20', country='RUSSIA') VALUES(206, 'Michael', 'Insatgram');
INSERT INTO TABLE user_data PARTITION(date_dt='2016-05-20', country='RUSSIA') VALUES(207, 'Chung', 'Instagram');
INSERT INTO TABLE user_data PARTITION(date_dt='2016-05-22', country='NEPAL') VALUES(208, 'Anna', 'Instagram');
show-partitions.png

默认情况下,表会创建在 HDFS 的 /user/hive/warehouse 路径(本例指定创建位置为 /user/spark/spark-sql-warehouse)。

由于我们的分区列为 date_dt 和 country 两列,相应的,可以在 HDFS 看到 user_data 的数据为以 date_dt 的取值作为第一级目录,country 的取值作为第二级目录进行存储。

hdfs-ls-1.png hdfs-ls-2.png

动态分区

动态分区可以自动识别分区,不需要明确指定分区。例如,如果数据已经存储在一个非分区的表中,现在需要将数据转储到一个分区表中,此时动态分区比较适合。
动态分区比静态分区更加耗时,且分区不可修改
使用动态分区特性需要在 hive-site.xml 中设置属性 hive.exec.dynamic.partition.mode= nonstrict

通过以下例子感受一下动态分区:

准备两个表,user_data_dyn 和 user_log_data。user_data_dyn 是分区表,以 date_dt 列和 country 列作为分区列。user_log_data 为非分区表,接下来将数据从非分区表 user_log_data 转储到分区表 user_data_dyn 中。

CREATE TABLE user_log_data (
user_id int,
user_name string,
site_data string,
date_dt string,
country string
);
INSERT INTO TABLE user_log_data VALUES(1001, 'John', 'Google', '2016-04-27', 'US');
INSERT INTO TABLE user_log_data VALUES(1002, 'Eric', 'Facebook', '2016-04-28', 'US');
INSERT INTO TABLE user_log_data VALUES(1003, 'Annie', 'Instagram', '2016-04-28', 'UK');
INSERT INTO TABLE user_log_data VALUES(1005, 'Ming', 'Google', '2016-04-29', 'CHINA');
INSERT INTO TABLE user_log_data VALUES(1006, 'Li', 'Facebook', '2016-04-29', 'CHINA');
INSERT INTO TABLE user_log_data VALUES(1007, 'Sota', 'Insatgram', '2016-04-29', 'JAPAN');
INSERT INTO TABLE user_log_data VALUES(1008, 'Yuto', 'Instagram', '2016-04-27', 'JAPAN');
INSERT INTO TABLE user_log_data VALUES(1009, 'Anna', 'Instagram', '2016-04-28', 'AUSTRALIA');
INSERT INTO TABLE user_log_data VALUES(1010, 'Ricky', 'Facebook', '2016-04-28', 'AUSTRALIA');
CREATE TABLE user_data_dyn (
user_id int,
user_name string,
site_data string
) PARTITIONED BY (
date_dt string,
country string
);
SET hive.exec.dynamic.partition = true;
SET hive.exec.dynamic.partition.mode = nonstrict; 

INSERT OVERWRITE TABLE user_data_dyn
PARTITION(date_dt, country)
SELECT user_id, user_name, site_data, date_dt, country FROM user_log_data; 

可以看到动态分区已经基于 date_dt 和 country 自动创建:

dynamic-partitions.png

对 user_data_dyn 中的分区执行删除操作,感受一下分区的便捷。不知道为什么,就想删掉那个叫 JAPAN 的 country:

alter table user_data_dyn drop partition (date_dt='2016-04-27', country='JAPAN');
drop-partitions.png

最后对 静态分区 和 动态分区 做一下对比:

分区方式 优点 缺点
静态分区 速度快,分区设定后可以更改 需要明确指定分区
动态分区 速度慢,分区不可更改 自动创建分区
上一篇下一篇

猜你喜欢

热点阅读