`

转:hive分区表

 
阅读更多

所介绍内容基本上是翻译官方文档,比较肤浅,如有错误,请指正!
hive中创建分区表没有什么复杂的分区类型(范围分区、列表分区、hash分区、混合分区等)。分区列也不是表中的一个实际的字段,而是一个或者多个伪列。意思是说在表的数据文件中实际上并不保存分区列的信息与数据。
下面的语句创建了一个简单的分区表:

create table partition_test
(member_id string,
name string
)
partitioned by (
stat_date string,
province string)
row format delimited fields terminated by ',';

这个例子中创建了stat_date和province两个字段作为分区列。通常情况下需要先预先创建好分区,然后才能使用该分区,例如:

alter table partition_test add partition (stat_date='20110728',province='zhejiang');

这样就创建好了一个分区。这时我们会看到hive在HDFS存储中创建了一个相应的文件夹:

$ hadoop fs -ls /user/hive/warehouse/partition_test/stat_date=20110728
Found 1 items
drwxr-xr-x - admin supergroup 0 2011-07-29 09:53 /user/hive/warehouse/partition_test/stat_date=20110728/province=zhejiang

每一个分区都会有一个独立的文件夹,下面是该分区所有的数据文件。在这个例子中stat_date是主层次,province是副层次,所有stat_date='20110728',而province不同的分区都会在/user/hive/warehouse/partition_test/stat_date=20110728 下面,而stat_date不同的分区都会在/user/hive/warehouse/partition_test/ 下面,如:

$ hadoop fs -ls /user/hive/warehouse/partition_test/
Found 2 items
drwxr-xr-x - admin supergroup 0 2011-07-28 19:46 /user/hive/warehouse/partition_test/stat_date=20110526
drwxr-xr-x - admin supergroup 0 2011-07-29 09:53 /user/hive/warehouse/partition_test/stat_date=20110728

注意,因为分区列的值要转化为文件夹的存储路径,所以如果分区列的值中包含特殊值,如 '%', ':', '/', '#',它将会被使用%加上2字节的ASCII码进行转义,如:

hive> alter table partition_test add partition (stat_date='2011/07/28',province='zhejiang');
OK
Time taken: 4.644 seconds

$hadoop fs -ls /user/hive/warehouse/partition_test/
Found 3 items
drwxr-xr-x - admin supergroup 0 2011-07-29 10:06 /user/hive/warehouse/partition_test/stat_date=2011%2F07%2F28
drwxr-xr-x - admin supergroup 0 2011-07-28 19:46 /user/hive/warehouse/partition_test/stat_date=20110526
drwxr-xr-x - admin supergroup 0 2011-07-29 09:53 /user/hive/warehouse/partition_test/stat_date=20110728

我使用一个辅助的非分区表partition_test_input准备向partition_test中插入数据:

hive> desc partition_test_input;
OK
stat_date string
member_id string
name string
province string

hive> select * from partition_test_input;
OK
20110526 1 liujiannan liaoning
20110526 2 wangchaoqun hubei
20110728 3 xuhongxing sichuan
20110728 4 zhudaoyong henan
20110728 5 zhouchengyu heilongjiang

然后我向partition_test的分区中插入数据:

hive> insert overwrite table partition_test partition(stat_date='20110728',province='henan') select member_id,name from partition_test_input where stat_date='20110728' and province='henan';
Total MapReduce jobs = 2
...
1 Rows loaded to partition_test
OK

还可以同时向多个分区插入数据,0.7版本以后不存在的分区会自动创建,0.6之前的版本官方文档上说必须要预先创建好分区:

hive>
> from partition_test_input
> insert overwrite table partition_test partition (stat_date='20110526',province='liaoning')
> select member_id,name where stat_date='20110526' and province='liaoning'
> insert overwrite table partition_test partition (stat_date='20110728',province='sichuan')
> select member_id,name where stat_date='20110728' and province='sichuan'
> insert overwrite table partition_test partition (stat_date='20110728',province='heilongjiang')
> select member_id,name where stat_date='20110728' and province='heilongjiang';
Total MapReduce jobs = 4
...
3 Rows loaded to partition_test
OK

特别要注意,在其他数据库中,一般向分区表中插入数据时系统会校验数据是否符合该分区,如果不符合会报错。而在hive中,向某个分区中插入什么样的数据完全是由人来控制的,因为分区键是伪列,不实际存储在文件中,如:


hive> insert overwrite table partition_test partition(stat_date='20110527',province='liaoning') select member_id,name from partition_test_input;
Total MapReduce jobs = 2
...
5 Rows loaded to partition_test
OK

hive> select * from partition_test where stat_date='20110527' and province='liaoning';
OK
1 liujiannan 20110527 liaoning
2 wangchaoqun 20110527 liaoning
3 xuhongxing 20110527 liaoning
4 zhudaoyong 20110527 liaoning
5 zhouchengyu 20110527 liaoning

可以看到在partition_test_input中的5条数据有着不同的stat_date和province,但是在插入到partition(stat_date='20110527',province='liaoning')这个分区后,5条数据的stat_date和province都变成相同的了,因为这两列的数据是根据文件夹的名字读取来的,而不是实际从数据文件中读取来的:

$ hadoop fs -cat /user/hive/warehouse/partition_test/stat_date=20110527/province=liaoning/000000_0
1,liujiannan
2,wangchaoqun
3,xuhongxing
4,zhudaoyong
5,zhouchengyu

下面介绍一下动态分区,因为按照上面的方法向分区表中插入数据,如果源数据量很大,那么针对一个分区就要写一个insert,非常麻烦。况且在之前的版本中,必须先手动创建好所有的分区后才能插入,这就更麻烦了,你必须先要知道源数据中都有什么样的数据才能创建分区。
使用动态分区可以很好的解决上述问题。动态分区可以根据查询得到的数据自动匹配到相应的分区中去。 
使用动态分区要先设置hive.exec.dynamic.partition参数值为true,默认值为false,即不允许使用:

hive> set hive.exec.dynamic.partition;
hive.exec.dynamic.partition=false
hive> set hive.exec.dynamic.partition=true;
hive> set hive.exec.dynamic.partition;
hive.exec.dynamic.partition=true

动态分区的使用方法很简单,假设我想向stat_date='20110728'这个分区下面插入数据,至于province插入到哪个子分区下面让数据库自己来判断,那可以这样写:

hive> insert overwrite table partition_test partition(stat_date='20110728',province)
> select member_id,name,province from partition_test_input where stat_date='20110728';
Total MapReduce jobs = 2
...
3 Rows loaded to partition_test
OK

stat_date叫做静态分区列,province叫做动态分区列。select子句中需要把动态分区列按照分区的顺序写出来,静态分区列不用写出来。这样stat_date='20110728'的所有数据,会根据province的不同分别插入到/user/hive/warehouse/partition_test/stat_date=20110728/下面的不同的子文件夹下,如果源数据对应的province子分区不存在,则会自动创建,非常方便,而且避免了人工控制插入数据与分区的映射关系存在的潜在风险。

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

hive> insert overwrite table partition_test partition(stat_date,province='liaoning')
> select member_id,name,province from partition_test_input where province='liaoning';
FAILED: Error in semantic analysis: Line 1:48 Dynamic partition cannot be the parent of a static partition 'liaoning'

动态分区可以允许所有的分区列都是动态分区列,但是要首先设置一个参数hive.exec.dynamic.partition.mode :

hive> set hive.exec.dynamic.partition.mode;
hive.exec.dynamic.partition.mode=strict

它的默认值是strick,即不允许分区列全部是动态的,这是为了防止用户有可能原意是只在子分区内进行动态建分区,但是由于疏忽忘记为主分区列指定值了,这将导致一个dml语句在短时间内创建大量的新的分区(对应大量新的文件夹),对系统性能带来影响。
所以我们要设置:
hive> set hive.exec.dynamic.partition.mode=nostrick;

再介绍3个参数:
hive.exec.max.dynamic.partitions.pernode (缺省值100):每一个mapreduce job允许创建的分区的最大数量,如果超过了这个数量就会报错
hive.exec.max.dynamic.partitions (缺省值1000):一个dml语句允许创建的所有分区的最大数量
hive.exec.max.created.files (缺省值100000):所有的mapreduce job允许创建的文件的最大数量

当源表数据量很大时,单独一个mapreduce job中生成的数据在分区列上可能很分散,举个简单的例子,比如下面的表要用3个map:
1
1
1
2
2
2
3
3
3

如果数据这样分布,那每个mapreduce只需要创建1个分区就可以了: 
         |1
map1 --> |1 
         |1 

         |2
map2 --> |2 
         |2 

         |3
map3 --> |3 
         |3
但是如果数据按下面这样分布,那第一个mapreduce就要创建3个分区: 

         |1
map1 --> |2 
         |3 

         |1
map2 --> |2 
         |3 

         |1
map3 --> |2 
         |3

下面给出了一个报错的例子:
hive> set hive.exec.max.dynamic.partitions.pernode=4;
hive> insert overwrite table partition_test partition(stat_date,province)
> select member_id,name,stat_date,province from partition_test_input distribute by stat_date,province;
Total MapReduce jobs = 1
...
[Fatal Error] Operator FS_4 (id=4): Number of dynamic partitions exceeded hive.exec.max.dynamic.partitions.pernode.. Killing the job.
Ended Job = job_201107251641_0083 with errors
FAILED: Execution Error, return code 2 from org.apache.hadoop.hive.ql.exec.MapRedTask

为了让分区列的值相同的数据尽量在同一个mapreduce中,这样每一个mapreduce可以尽量少的产生新的文件夹,可以借助distribute by的功能,将分区列值相同的数据放到一起:

hive> insert overwrite table partition_test partition(stat_date,province)
> select member_id,name,stat_date,province from partition_test_input distribute by stat_date,province;
Total MapReduce jobs = 1
...
18 Rows loaded to partition_test
OK

好了,关于hive的分区表先简单介绍到这里,后续版本如果有功能的更新我也会再更新。

分享到:
评论

相关推荐

    bdp2hive:生成hive分区表、sqoop导入数据至hive

    bdp2hive项目介绍一、概述项目主要是集成生成sqoop脚本和创建hive分区表组件。生成sqoop脚本组件主要通过传递的数据库信息查询数据库获取表字段与数据集之间的对照关系SQL语句,通过模板拼接成sqoop脚本,上传服务器...

    hive分区表分通表建表语句详解和例子

    ### Hive 分区表与分桶表详解 #### 一、Hive 分区表概念与应用场景 ...通过对以上Hive分区表的概念、创建方法及管理操作的了解,我们可以更加高效地管理和查询大型数据集,从而提高数据分析的效率和准确性。

    修改hive表分区名称

    ### 修改Hive表分区名称的方法 在大数据处理领域中,Apache Hive是一款广泛使用的数据仓库工具,它能够将结构化的数据文件映射为一张数据库表,并提供类SQL查询功能,使得用户能够通过简单的SQL语句来处理存储在...

    BLOG_如何将一个普通表转换为分区表.pdf

    从提供的文件内容可以看出,本文主要介绍的是如何将一个非分区表转换为分区表,其中涉及了四种不同的方法,并且强调了每种方法的执行细节以及注意事项。 1. Export/Import方法 Export/Import方法是最传统的转换策略...

    Hive表分区

    Hive表分区,里面有比较详细的Hive表分区方法,希望能够有所帮助。

    大数据系列4:Hive – 基于HADOOP的数据仓库

    1. **元数据存储**:Hive使用一个元数据存储来管理关于表、分区、列等的信息。通常,元数据存储在关系数据库如MySQL或Derby中,这些信息用于解析HiveQL语句。 2. **Hive服务器**:也称为Hive Metastore Server,...

    hive数据分区时分区字段不可为中文。.doc

    - **Hive 数据分区**是 Hive 表的一种组织方式,它允许将表中的数据按照某个列(分区键)的值进行划分,存储在不同的目录下。 - 分区有助于提高查询效率,因为当查询指定分区时,Hive 只需要扫描相关的分区,而...

    hive分区导入

    3. 使用HiveQL创建和管理分区表。 4. Sqoop工具的使用,包括安装、配置、数据导入导出命令。 5. SQL性能优化,特别是对于大型数据集的查询。 6. Oozie在工作流中的角色,如何配合Hive和Sqoop进行任务调度。 7. 数据...

    Hive分区表和分桶表.md

    Hive分区表和分桶表,进阶篇

    龙战于野大数据MR原理启动hive查询表分区.docx

    4. 查看库表:`hive> show databases/table;` 5. 查看表结构:`hive> desc table_name;` Hive查询表分区的MR原理启动是指使用MapReduce来处理数据的方式,该方式可以提高数据查询的效率和性能。

    第6章:Hive性能优化及Hive3新特性1

    - **分区表**:为了解决普通表查询时不必要的数据加载问题,Hive引入了分区表。通过将数据按特定字段(通常是时间戳或类别)划分为不同的分区,每个分区对应HDFS上的一个目录。这使得查询时只需处理与条件匹配的...

    第四十九章:Hive数据仓库工具1

    Hive 数据模型包括内部表(Internal Table)、外部表(External Table)、分区(Partition)和桶(Bucket)。内部表的数据由 Hive 管理,当删除表时,数据也会被删除。外部表仅管理表的元数据,数据的生命周期独立于...

    大数据学习:Hive数据操作语言.pdf

    动态分区、静态分区和混合分区是Hive数据操作语言的高级操作,用于将数据插入到分区表中。动态分区的语法格式如下: INSERT INTO table_name PARTITION (partcol1=val1, partcol2=val2 ...) VALUES (value1, value2...

    Hive查询优化:Sort By、Order By、Cluster By、Distribute深入解析

    3. **数据抽象**:Hive使用表和分区等概念来抽象底层数据存储,使得用户可以像操作传统数据库一样操作Hadoop集群中的数据。 4. **扩展性**:Hive设计用于处理大规模数据集,可以水平扩展以适应更大的数据量。 5. **...

    大数据实验六实验报告:熟悉Hive的基本操作

    通过这个实验,学生能够掌握Hive的基本操作,包括创建表(内部表和分区表)、数据导入、数据查询以及动态分区的使用,这些都是大数据分析中的关键步骤。同时,了解如何在Windows环境下配置和使用Ubuntu虚拟机,以及...

    大数据学习:Hive数据定义语言.pdf

    本文档将详细讲解 Hive 的数据定义语言(DDL),包括数据库的基本操作、数据表的基本操作、分区表、分桶表、临时表、视图、索引等内容。 数据库的基本操作 Hive 中创建数据库的语法格式如下: CREATE (DATABASE|...

    Hive与Hbase的整合

    Hive与Hbase的整合,集中两者的优势,使用HiveQL语言,同时具备了实时性

    hive

    2. **元数据管理**:Hive 有一个元数据存储库,保存着关于表、分区、字段等信息。这些元数据可以帮助 Hive 理解数据的结构,使得用户能够通过 SQL 方式进行查询。 3. **灵活性**:Hive 支持多种数据模型,包括行...

    spark或mr引擎插入的数据,hive表查询数据为0

    ### Spark或MR引擎插入的数据,Hive表查询数据为0的问题解析 #### 问题背景与现象 在大数据处理场景中,经常会遇到使用不同执行引擎(如Spark、MapReduce (MR) 或 Tez)进行数据处理的情况。其中一种常见的问题是...

    Hive-工具篇_hive_

    - **表的创建**:Hive中的表可以分为分区表和非分区表,分区有助于提高查询效率,将大表划分为更小、更易管理的部分。 - **数据类型**:Hive支持多种数据类型,包括基本类型(如STRING、INT、FLOAT)和复杂类型...

Global site tag (gtag.js) - Google Analytics