所介绍内容基本上是翻译官方文档,比较肤浅,如有错误,请指正!

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的分区表先简单介绍到这里,后续版本如果有功能的更新我也会再更新。

hive中简单介绍分区表的更多相关文章

  1. hive中简单介绍分区表(partition table)——动态分区(dynamic partition)、静态分区(static partition)

    一.基本概念 hive中分区表分为:范围分区.列表分区.hash分区.混合分区等. 分区列:分区列不是表中的一个实际的字段,而是一个或者多个伪列.翻译一下是:“在表的数据文件中实际上并不保存分区列的信 ...

  2. hive 中简单的udf函数编写

    .注册函数,使用using jar方式在hdfs上引用udf库. $hive.注销函数,只需要删除mysql的hive数据记录即可. delete from func_ru ; delete from ...

  3. hive中导入json格式的数据(hive分区表)

    hive中建立外部分区表,外部数据格式是json的如何导入呢? json格式的数据表不必含有分区字段,只需要在hdfs目录结构中体现出分区就可以了 This is all according to t ...

  4. Hive中的三种不同的数据导出方式介绍

    问题导读:1.导出本地文件系统和hdfs文件系统区别是什么?2.带有local命令是指导出本地还是hdfs文件系统?3.hive中,使用的insert与传统数据库insert的区别是什么?4.导出数据 ...

  5. 计算机启动过程的简单介绍 计算机启动流程 计算机BIOS作用 POST 开机自检 计算机启动顺序 分区表 操作系统启动

    原文地址:4.计算机启动过程的简单介绍 计算机启动流程 计算机BIOS作用 POST 开机自检 计算机启动顺序 分区表 操作系统启动 计算机的启动

  6. [原创]关于mybatis中一级缓存和二级缓存的简单介绍

    关于mybatis中一级缓存和二级缓存的简单介绍 mybatis的一级缓存: MyBatis会在表示会话的SqlSession对象中建立一个简单的缓存,将每次查询到的结果结果缓存起来,当下次查询的时候 ...

  7. 简单介绍一下R中的几种统计分布及常用模型

    统计学上分布有很多,在R中基本都有描述.因能力有限,我们就挑选几个常用的.比较重要的简单介绍一下每种分布的定义,公式,以及在R中的展示. 统计分布每一种分布有四个函数:d――density(密度函数) ...

  8. 决策树简单介绍(二) Accord.Net中决策树的实现和使用

    决策树介绍 决策树是一类机器学习算法,可以实现对数据集的分类.预测等.具体请阅读我另一篇博客(http://www.cnblogs.com/twocold/p/5424517.html). Accor ...

  9. Qt中利用QTime类来控制时间,这里简单介绍一下QTime的成员函数的用法:

    Qt中利用QTime类来控制时间,这里简单介绍一下QTime的成员函数的用法: ------------------------------------------------------------ ...

随机推荐

  1. yum中baserul路径中的空格

    配置yum源时,比如指定本地挂载的光盘时,路径中包含空格.在不使用链接的情况下,用"\"进行转义不行,把路径加单.双引号也不可行.正确做法是把空格用%20代替.同理,其他不可识别的 ...

  2. Picker组件封装

    在开发APP的过程中,我们可能会遇上软件中需要有很多下拉选择样式,就像之前我做的那个<房贷计算器>一样,有很多下拉选择,如果没有将Picker封装起来共用是很麻烦的. 安装插件 在Reac ...

  3. cordova发送邮件插件:ngcordova plugin-Email Composer

    这是ngcordova里边的一个发送邮件的插件,具体的使用方法为: (参考文档:http://ngcordova.com/docs/plugins/emailComposer/) 1.首先下载插件: ...

  4. Matlab的GUI参数传递方式总结

    MATLAB GUI传递方式 1.全局变量: 2.作为函数的参数传递: 3.利用控件的userdata数据: 4.为handles结构体添加新字段: 5.setappdata函数为句柄添加数据: 6. ...

  5. 转 【O2O案例】汽车后市场垂直化电子商务:平业模式解析

    核心提示:一.商业模式简介.汽车后市场垂直化电子商务是我在2010年初开始筹划,起因是在淘宝工作期间运营汽车类目后遇到很多问题无决,由于 一.商业模式简介. 汽车后市场垂直化电子商务是我在2010年初 ...

  6. 兼容性调试-- 在谷歌浏览器中,td 设置colspan的失效的问题

    通过设置table width="100%"table-layout="fixed" 解决

  7. [CAMCOCO][C#]我的系统架构.服务器端.(二)----DATA层

    这一层在园子里有很多很多的介绍了,这层写好之后老胡也没多研究,基本上就是参考的园子里大咖们的写法,具体的说明老胡也细说不了了,把接口和思路简单描述一下就好,如果有问题还是那句话,感谢您不吝赐教,老胡这 ...

  8. centos安装与基本使用

    1.      插入安装光盘 2.      进入试用 3.      在试用的桌面系统选择安装到硬盘 4.      选择安装语言 5.      选择基本存储或者专门的存储设备 6.      - ...

  9. 无法解决 equal to 运算中 "Chinese_PRC_CI_AS" 和 "Chinese_PRC_90_CI_AI" 之间的排序规则冲突。的解决方法

    在SQL SERVICE的查询的时候遇到了“无法解决 equal to 运算中 "Chinese_PRC_CI_AS" 和 "Chinese_PRC_90_CI_AI&q ...

  10. Cocos2d-JS中JavaScript继承

    JavaScript语言本身没有提供类,没有其它语言的类继承机制,它的继承是通过对象的原型实现的,但这不能满足Cocos2d-JS引擎的要求.由于Cocos2d-JS引擎是从Cocos2d-x演变而来 ...