hive关于partition的学习

为什么在Hive中使用分区

首先要了解这一点,让我们看一个场景。可以说有一家跨国银行,名称为ABC_BANK,跨多个国家。现在,我们有了一个表,其中包含名为“ new_cust ”的新客户的信息。假设您想找出来自“USA”的新客户数。hive这样做如下
搜索所有国家,并过滤’USA’的记录
计算“美国”的新客户数量
这样可以提供正确的输出,但是我们可以优化它,以便Hive更快地获取记录。如果Hive在已经存在属于USA的记录的地方已经很新了,那么它不必遍历所有国家/地区的记录该怎么办?这可以使用Hive Partition来实现。

让我们将“ new_cust”表中的“国家/地区”列转换为Hive分区列。这将为每个国家/地区创建一个分区(基本上是一个文件夹),并将其相关数据移入其中。因此,下一次当我们运行查询以从美国或任何其他国家/地区获取新客户时,Hive会知道它需要查看该特定分区/文件夹内部并获取相关数据,从而减少了花费的总时间并提高了性能。

创建表过程中创建partition

您可以在Hive表上使用Partitioned By子句创建分区。这些列可以在现有表上进行分区,也可以在创建新的Hive表时进行分区。管理表/外区表和外部表均支持列分区。分区的基本语法如下

create [external ]table tbl_nm
(col1 datatyape , col2 datatype ..)
Partitioned By (coln datatype);

内部表创建分区

在内部创建表时,将在HDFS中使用相同的名称创建一个文件夹,其中将存储所有数据。在创建分区列时,Hive在父表文件夹中创建了更多文件夹,然后存储了数据。这可能会造成混淆,因此让我们检查一个示例。

让我们创建一个名为int_test的表,其中包含客户ID和客户名称以及客户所属的州。我们将创建一个分区列“ Country”。

create table int_test
(
cust_id int,
cust_nm string,
state string
)
partitioned by (country string)

//HDFS
/user/hive/warehouse/int_test

alter table int_test add if not exists partition(country = 'USA')
alter table int_test add if not exists partition(country = 'INDIA')

//HDFS
/user/hive/warehouse/int_test
/user/hive/warehouse/int_test/country=INDIA
/user/hive/warehouse/int_test/country=USA

您会在上面看到,创建表时,在HDFS中创建了名为“ int_test”的文件夹。接下来,当您添加分区[USA,INDIA]时,这些分区将成为在表文件夹[int_test]中创建的新文件夹。当您插入数据时,数据将驻留在它们各自的分区中。

外部表上创建分区

您可以像在内部表上一样在Hive外部表上创建分区。唯一的区别是,当您在内部表上删除分区时,数据也会被删除,但是当您在外部表上删除分区时,数据将保持原样。

静态分区

在Hive静态分区中,我们手动指定需要在其中插入数据的分区。在插入之前,您需要设置属性’ set hive.mapred.mode = strict '。同样,由于一次性插入了整个数据,因此这比动态分区要快得多。

让我们将数据插入之前创建的int_test表中,并将数据加载到国家/地区“ CANADA”中。

insert into int_test partition(country = 'CANADA')
Select 111 , 'Mark Anthony' , 'Ottawa'
union all
Select 112 , 'Nancy Hugh' , 'Ottawa'
//HDFS
/ user/ hive/ warehouse/ int_test/ country=CANADA/ 000000_0
//Data
111,Mark Anthony,Ottawa
112,Nancy Hugh,Ottawa

在这里,您会看到一个名为“ Canada”的分区已创建,并且已将数据插入其中。您还可以创建另一个分区“Norway”,并将数据插入其中。我们不必在Select中指定Partition列。

在这种方法中,由于我们要转储整个数据,因此插入速度很快,但是由于您每次可以将数据插入1个分区中,因此整体插入速度很慢。

注意:当您使用插入到时,会被添加到分区中的任何现有数据中。但是,当您使用“insert overwrite ”时,您将删除分区中的现有数据并插入新数据。

动态分区

使用Hive动态分区,您可以创建数据并将其插入到多个分区中。您不必事先指定分区名称,只需指定充当分区的列,Hive就会为该列中的每个唯一值创建一个分区。

您需要启用的配置是

SET hive.exec.dynamic.partition = true;
SET hive.exec.dynamic.partition.mode =nostrict;
insert into int_test partition(country)
Select 111 , 'Mark Anthony' , 'Ottawa', 'Canada'
union all
Select 112 , 'Nancy Hugh' , 'California' , 'USA'
union all
Select 113 , 'Will Doughlas' , 'Michigan' , 'USA'
union all
Select 114 , 'Balwas Singh' , 'Delhi' , 'INDIA'
//HDFS
/user/hive/warehouse/int_test/country=Canada
/user/hive/warehouse/int_test/country=INDIA
/user/hive/warehouse/int_test/country=USA

在上面的示例中,动态创建了3个分区。当您要一次将包含多个分区的数据插入表中时,此功能很有用。当然,这将比静态分区慢,因为编译器需要弄清楚每行所属的位置。另外一个区别是,与静态分区不同,我们必须在select语句中提及分区列的值。

添加分区

在表Int_Test中,我们已经有几个国家/地区分区。如果我们想手动添加更多的国家分区,例如:迪拜和尼泊尔,该怎么办?语法如下

#alter table tbl_nm [add if not exists] partition( col_nm =’value’ , …..) location ‘loc’

alter table int_test add if not exists partition(country = 'Dubai')
alter table int_test add if not exists partition(country = 'Nepal')

重命名分区

使用此功能,您可以重命名现有的Hive分区值。让我们看一个示例,其中我们将“分区值美国”更改为美利坚合众国。以下是重命名Hive分区的语法

#alter table table_name PARTITION (col = ‘value’) RENAME TO PARTITION (col = ‘new_value’);

alter table int_test partition(country = 'USA') rename to partition(country = 'United States of America')

删除分区

删除Hive分区非常简单,只需记住,当删除内部表的分区时,数据将被删除,但是当您从外部表删除时,数据将保留在外部位置。语法如下

#alter table tbl_nm drop if exists partition (col = ‘value’ , …..)

alter table int_test drop if exists partition (country = 'Canada')

Hive分区的缺点

Hive分区是一个非常强大的功能,但是像每个功能一样,我们应该知道何时使用和何时避免。
如果我们正在运行的所有查询都在完整的数据集上,那么对数据进行分区就没有意义了,因为每次我们都要处理所有记录时。
应该为where子句中经常使用的列选择分区列。
我们选择分区的列应具有更多的唯一数据。例如,如果不是使用“国家/地区”列进行分区,而是在“客户”列上进行分区,则将创建成千上万个分区,这将给元存储和查询处理带来麻烦。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值