一、基本概念

hive中分区表分为:范围分区、列表分区、hash分区、混合分区等。

分区列:分区列不是表中的一个实际的字段,而是一个或者多个伪列。翻译一下是:“在表的数据文件中实际上并不保存分区列的信息与数据”,这个概念十分重要,要记住,后面是经常用到。

1.1 创建数据表

下面的语句创建了一个简单的分区表:

create table partition_test(
member_id string,
name string
)
partitioned by
(
stat_date string,
province string
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';

1.2 创建分区

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

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

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

hive> dfs -ls /user/ticketdev/hive/warehouse/partition_test/stat_date=20141113;
Found 1 items
drwxr-xr-x - ticketdev ticketdev 0 2014-11-13 17:50 /user/ticketdev/hive/warehouse/partition_test/stat_date=20141113/province=jilin
h

每一个分区都会有一个独立的文件夹,在这个例子中stat_date是主文件夹,province是子文件夹,如:

hive> alter table partition_test add partition (stat_date='',province='beijing');
OK
Time taken: 0.119 seconds
hive> dfs -ls /user/ticketdev/hive/warehouse/partition_test/stat_date=20141113/;
Found 2 items
drwxr-xr-x - ticketdev ticketdev 0 2014-11-13 18:06 /user/ticketdev/hive/warehouse/partition_test/stat_date=20141113/province=beijing
drwxr-xr-x - ticketdev ticketdev 0 2014-11-13 17:50 /user/ticketdev/hive/warehouse/partition_test/stat_date=20141113/province=jilin

二、静态分区

2.1 数据准备

基本知识介绍到这里,下面开始插入数据。我使用一个辅助的非分区表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

2.2 添加数据

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

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

还可以同时向多个分区插入数据:

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

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

hive> insert overwrite table partition_test partition(stat_date='',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='' 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='',province)
> select member_id,name,province from partition_test_input where stat_date='';
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允许创建的文件的最大数量

hive中简单介绍分区表(partition table)——动态分区(dynamic partition)、静态分区(static partition)的更多相关文章

  1. hive中简单介绍分区表

    所介绍内容基本上是翻译官方文档,比较肤浅,如有错误,请指正! hive中创建分区表没有什么复杂的分区类型(范围分区.列表分区.hash分区.混合分区等).分区列也不是表中的一个实际的字段,而是一个或者 ...

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

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

  3. hive SQL 静态分区和 动态分区

    Hive 分区介绍: hive中简单介绍分区表(partition table),含动态分区(dynamic partition)与静态分区(static partition) hive中创建分区表没 ...

  4. Hive中静态分区和动态分区总结

    目录 背景 第一部分 静态分区 第二部分 动态分区 第三部分 两者的比较 第四部分 动态分区使用的问题 参考文献及资料 背景 在Hive中有两种类型的分区:静态分区(Static Partitioni ...

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

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

  6. PLSQL_性能优化系列09_Oracle Partition Table数据分区表

    2014-08-22 Created By BaoXinjian

  7. 什么是hive的静态分区和动态分区,它们又有什么区别呢?hive动态分区详解

    面试官问我,什么是hive的静态分区和动态分区,这题我会呀. 简述 分区是hive存放数据的一种方式,将列值作为目录来存放数据,就是一个分区,可以有多列. 这样查询时使用分区列进行过滤,只需根据列值直 ...

  8. linux中LVM介绍及实验过程

    LVM LVM这个词不仅一次出现过,在安装Centos时,磁盘分区时,默认分区就是使用LVM方式分区:再一个就是在OpenStack部署时候用到LVM作为后端存储.对LVM的理解还是不太清晰,查询资料 ...

  9. hive操作简单总结

    Hive DDL.DML操作 背景介绍 • 一.DDL操作(数据定义语言)包括:Create.Alter.Show.Drop等. • create database- 创建新数据库 • alter d ...

随机推荐

  1. C/C++中结构体(struct)

    c++ 里面struct可以new,另外: C++中,struct关键字与Class关键字基本是一样的,但是,有两点不同 1 struct定义的数据类型里面所有成员默认级别都是共有的,而class里面 ...

  2. 安装express并创建工程

    安装express npm install express-generator -g 使用命令创建express工程, express projectName 生成express相应的工程结构 bin ...

  3. POJ 2135 Farm Tour && HDU 2686 Matrix && HDU 3376 Matrix Again 费用流求来回最短路

    累了就要写题解,近期总是被虐到没脾气. 来回最短路问题貌似也能够用DP来搞.只是拿费用流还是非常方便的. 能够转化成求满流为2 的最小花费.一般做法为拆点,对于 i 拆为2*i 和 2*i+1.然后连 ...

  4. NoSQL现状

    经过了至少4年的激烈争论,现在是对NoSQL的现状做一个阶段性结论的时候了.围绕着NoSQL发生了如此之多的事情,以至于很难对其作出一个简单概括,也很难判断它达到了什么目标以及在什么方面没有达到预期. ...

  5. 两种方法获取MyBatis刚刚插入的id

    主要就是在xml文件中的写法,其他省略 方法一: <insert id="insert" parameterType="com.xxx.xxxx.pojo.User ...

  6. c#使用QQ邮箱的SSL收发邮件

    c#使用SMTP.QQ.COM的SSL验证时,收发邮件,请勿设置端口,代码如下: (1)虽然SSL端口是465,但是,在代码里,不能直接设置端口,很奇怪?挺奇怪,好吧腾讯SSL好像用的是587端口!! ...

  7. 相声段子:How Are You

    /**************************************************************** File name : HowAreYou Author : 叶飞影 ...

  8. Maven 默认插件以及功能

    Maven 默认插件 已知 Maven 使用 plugin 来执行实际操作的,在默认情况下,Maven 会绑定以下几个插件来完成基本操作. plugin function life cycle pha ...

  9. frp官方中文文档

    frp 是一个可用于内网穿透的高性能的反向代理应用,支持 tcp, udp, http, https 协议. 目录 frp 的作用 开发状态 架构 使用示例 通过 ssh 访问公司内网机器 通过自定义 ...

  10. 【转】asm.js 和 Emscripten 入门教程

      Web 技术突飞猛进,但是有一个领域一直无法突破 ---- 游戏. 游戏的性能要求非常高,一些大型游戏连 PC 跑起来都很吃力,更不要提在浏览器的沙盒模型里跑了!但是,尽管很困难,许多开发者始终没 ...