首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

大数据入门基础系列之浅谈Hive的分区表

在前面的博文里,我已经介绍了

在Hive里,为什么要分区?

庞大的数据集可能需要耗费大量的时间去处理。在许多场景下,可以通过分区或切片的方法减少每一次扫描总数据量,这种做法可以显著地改善性能。

数据会依照单个或多个列进行分区,通常按照时间、地域或者是商业维度进行分区。比如vido表,分区的依据可以是电影的种类和评级,另外,按照拍摄时间划分可能会得到更一致的结果。为了达到性能表现的一致性,对不同列的划分应该让数据尽可能均匀分布。最好的情况下,分区的划分条件总是能够对应where语句的部分查询条件。

Hive的分区使用HDFS的子目录功能实现。每一个子目录包含了分区对应的列名和每一列的值。但是由于HDFS并不支持大量的子目录,这也给分区的使用带来了限制。我们有必要对表中的分区数量进行预估,从而避免因为分区数量过大带来一系列问题。

Hive查询通常使用分区的列作为查询条件。这样的做法可以指定MapReduce任务在HDFS中指定的子目录下完成扫描的工作。HDFS的文件目录结构可以像索引一样高效利用。

为了对表进行合理的管理以及提高查询效率,Hive可以将表组织成“分区”。

分区是表的部分列的集合,可以为频繁使用的数据建立分区,这样查找分区中的数据时就不需要扫描全表,这对于提高查找效率很有帮助。

分区是一种根据“分区列”(partition column)的值对表进行粗略划分的机制。Hive中的每个分区对应数据库中相应分区列的一个索引,每个分区对应着表下的一个目录,在HDFS上的表现形式与表在HDFS上的表现形式相同,都是以子目录的形式存在。

一个表可以在多个维度上进行分区,并且分区可以嵌套使用。建分区需要在创建表时通过PARTITIONED BY子句指定,例如:

CREATE TABLE logs(timestamp BIGINT,line STRING)PARTITIONED BY(date STRING,country STRING);

在将数据加载到表内之前,需要数据加载人员明确知道所加载的数据属于哪一个分区。

使用分区在某些应用场景下能给有效地提高性能,当只需要遍历某一个小范围内的数据或者一定条件下的数据时,它可以有效减少扫描数据的数量,前提是需要将数据导入到分区内。

注意:PARTITONED BY子句中定义的列是表中正式的列(分区列),但是数据文件内并不包含这些列。

分区操作

  注意:注意:普通表(外部表、内部表)、分区表这三个都是对应HDFS上的目录,桶表对应是目录里的文件。

Hive 的分区通过在创建表时启动 PARTITION BY 实现,用来分区的维度并不是实际数据的某一列,具体分区的标志是由插入内容时给定的。当要查询某一分区的内容时可以采用 WHERE 语句, 例如使用 “WHERE tablename.partition_key>a” 创建含分区的表。

创建分区语法如下。

CREATE TABLE table_name(  ...  )  PARTITION BY (dt STRING,country STRING)

为Hive分区表创建分区

Hive 中创建分区表没有什么复杂的分区类型(范围分区、列表分区、hash 分区,混合分区等)。分区列也不是表中的一个实际的字段,而是一个或者多个伪列。意思是说,在表的数据文件中实际并不保存分区列的信息与数据。

创建一个简单的分区表。

Hive>createtablepartition_test(member_id string,name string)partitioned by(stat_date string,province string) row format delimited fields terminated by ',';

这个例子中创建了 stat_date 和 province 两个字段作为分区列。

通常情况下需要预先创建好分区,然后才能使用该分区。例如:

Hive>alter tablepartition_testadd partition(stat_date='2015-01-18',province='beijing');

这样就创建了一个分区。

这时会看到 Hive 在HDFS 存储中创建了一个相应的文件夹。

$ hadoop fs -ls /user/Hive/warehouse/partition_test/stat_date=2015-01-18

/user/Hive/warehouse/partition_test/stat_date=2015-01-18/province=beijing显示刚刚创建的分区

每一个分区都会有一个独立的文件夹(目录),在上面例子中,stat_date 是主层次,province 是 副层次。

往Hive分区表里插入数据

使用一个辅助的非分区表 partition_test_input准备向 partition_test 中插入数据,实现步骤如下。

1) 查看非分区表partition_test_input 表的结构,命令如下。

Hive> desc partition_test_input;

2) 查看非分区表partition_test_input 的数据,命令如下。

Hive> select * from partition_test_input;

3) 向分区表partition_test 的分区中插入数据,命令如下。

insert overwrite table partition_test partition(stat_date='2015-01-18',province='jiangsu')select member_id,name frompartition_test_inputwhere stat_date='2015-01-18' and province='jiangsu';

注意:看好。这里是假设数据是从非分区表partition_test_input 里来的。

向分区表里的多个分区插入数据,命令如下。

Hive> frompartition_test_input

insert overwrite tablepartition_test partition(stat_date='2015-01-18',province='jiangsu')select member_id,name from partition_test_input where stat_date='2015-01-18' and province='jiangsu'

insert overwrite tablepartition_test partition(stat_date='2015-01-28',province='sichuan')select member_id,name from partition_test_input where stat_date='2015-01-28' and province='sichuan'

insert overwrite tablepartition_test partition(stat_date='2015-01-28',province='beijing')select member_id,name from partition_test_input where stat_date='2015-01-28' and province='beijing';

注意:看好。这里是假设数据是从非分区表partition_test_input 里来的。

Hive分区表的动态分区

  按照上面的方法向分区表中插入数据,如果数据源很大,针对一个分区就要写一个 insert ,非常麻烦。使用动态分区可以很好地解决上述问题。动态分区可以根据查询得到的数据自动匹配到相应的分区中去。

动态分区可以通过下面的设置来打开:

动态分区的使用方法很简单,假设向 stat_date='2015-01-18' 这个分区下插入数据,至于 province 插到哪个子分区下让数据库自己来判断。stat_date 叫做静态分区列,province 叫做动态分区列。

Hive>insert overwrite table partition_testpartition(stat_date='2015-01-18',province)

select member_id,name province frompartition_test_inputwhere stat_date='2015-01-18';

注意:Hive分区表的动态分区不允许主分区采用动态列而副分区采用静态列,这样将导致所有的主分区都要创建副分区静态列所定义的分区。

每一个 MapReduce Job 允许创建的分区的最大数量,如果超过这个数量就会报错(默认值100)。

一个 dml 语句允许创建的所有分区的最大数量(默认值100)。

所有 MapReduce Job 允许创建的文件的最大数量(默认值10000)。

尽量让分区列的值相同的数据在同一个 MapReduce 中,这样每一个 MapReduce 可以尽量少地产生新的文件夹,可以通过 DISTRIBUTE BY 将分区列值相同的数据放到一起,命令如下。

Hive> insert overwrite tablepartition_test partition(stat_date,province)

select memeber_id,name,stat_date,province frompartition_test_inputdistribute by stat_date,province;

下一篇,我会详细剖析Hive的桶表里各个细分知识。

http://www.cnblogs.com/zlslch/http://www.cnblogs.com/lchzls/

看完本文有收获?请转发分享给更多人

关注「大数据躺过的坑」,提升大神技能

觉得不错,请点赞和留言

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20171213G11CJ200?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券