hive分区

动态分区

如果往hive里面创建的分区有很多,假设按照某个字段进行分区存储,需要写很多sql语句。hive提供了一种动态分区的功能,可以基于查询参数的位置去推断分区的名称,从而建立分区。
首先看下数据集:

1,小明1,male,24,lol-book-movie,beijing:xisanqi-shanghai:pudong
2,小明2,male,25,lol-book-movie,beijing:xisanqi-shanghai:pudong
3,小明3,female,23,lol-book-movie,beijing:xisanqi-shanghai:pudong
4,小明4,male,23,lol-book-movie,beijing:xisanqi-shanghai:pudong
5,小明5,female,24,lol-movie,beijing:xisanqi-shanghai:pudong
6,小明6,male,25,lol-book-movie,beijing:xisanqi-shanghai:pudong
7,小明7,female,23,lol-book,beijing:xisanqi-shanghai:pudong
8,小明8,female,24,lol-book,beijing:xisanqi-shanghai:pudong
9,小明9,male,23,lol-book-movie,beijing:xisanqi-shanghai:pudong

首先创建一张表来保存这些数据,还未进行分区

hive> create table one (id int,name string,hobby array<string>,address 
      map<string,string) row format delimited fields terminated by ','
      collection items terminated by '-' 
      map keys terminated by ':'
      lines terminated by '\n';                

开启动态分区,默认是false

hive> set hive.exec.dynamic.partition=true;#默认是false
      set hive.exec.dynamic.partition.mode=nonstrict;#开启允许所有分区都是动态的,否则必要要有一个静态分区才能使用,且静态分区要在动态分区的前面

注意: cli模式下的set参数只能是本次会话有效,退出后就无效。如果想永久有效,需要去hive-site.xml下设置。但cli模式下的设置优先级大于hive-site.xml设置。
建立分区表

create table two (id int,name string,hobby array<string>,address map<string,string>) 
partitioned by (sex string,age int);

根据表one中的sex和age字段进行分区,注意分区的字段sex,age只能放在hive数据字段的后面。
注意:使用,insert…select 往表中导入数据时,查询的字段个数必须和目标的字段个数相同,不能多,也不能少,否则会报错。但是如果字段的类型不一致的话,则会使用null值填充,不会报错。而使用load data形式往hive表中装载数据时,则不会检查。如果字段多了则会丢弃,少了则会null值填充。同样如果字段类型不一致,也是使用null值填充。

from one 
insert into table two partition (sex,age)
select id,name,hobby,address,sex,age destribute by sex,age;#destribute by是控制在map端如果把数据拆分给reduce端,这里加不加都可。hive会根据reduce的个数进行数据分发,默认采用hash算法。

age和sex的顺序也不行错。
查看查询结果

hive> select * from two;
OK
7	小明7	["lol","book"]	{"beijing":"xisanqi","shanghai":"pudong"}	female	23
3	小明3	["lol","book","movie"]	{"beijing":"xisanqi","shanghai":"pudong"}	female	23
8	小明8	["lol","book"]	{"beijing":"xisanqi","shanghai":"pudong"}	female	24
5	小明5	["lol","movie"]	{"beijing":"xisanqi","shanghai":"pudong"}	female	24
9	小明9	["lol","book","movie"]	{"beijing":"xisanqi","shanghai":"pudong"}	male	23
4	小明4	["lol","book","movie"]	{"beijing":"xisanqi","shanghai":"pudong"}	male	23
1	小明1	["lol","book","movie"]	{"beijing":"xisanqi","shanghai":"pudong"}	male	24
6	小明6	["lol","book","movie"]	{"beijing":"xisanqi","shanghai":"pudong"}	male	25
2	小明2	["lol","book","movie"]	{"beijing":"xisanqi","shanghai":"pudong"}	male	25

hive> show partitions two;
OK
sex=female/age=23
sex=female/age=24
sex=male/age=23
sex=male/age=24
sex=male/age=25
Time taken: 0.251 seconds, Fetched: 5 row(s)

静态分区

在插入数据时指定分区

create table three (id int,name string,hobby array<string>,address 
map<string,string>) 
partitioned by (sex string,age int);
from one
insert into table three partition(age=22,sex='female')
select id,name,hobby,addr;

半自动分区

一部分是静态分区一部分是动态分区

create table five (id int,name string,habby array<string>,addr 
map<string,string> partititoned by (sex string,age int);

只需要动态分区age

from one 
insert into table five partition (sex='male',age)
select id,name,hobby,address,age;

order by和sort by

order by

Hive中的order by跟传统的sql语言中的order by作用是一样的,会对查询的结果做一次全局排
序,所以说,只有hive的sql中制定了order by所有的数据都会到同一个reducer进行处理(不管
有多少map,也不管文件有多少的block只会启动一个reducer)。但是对于大量数据这将会消耗很
长的时间去执行。
    这里跟传统的sql还有一点区别:如果指定了hive.mapred.mode=strict(默认值是
nonstrict),这时就必须指定limit来限制输出条数,原因是:所有的数据都会在同一reducer端
进行,数据量大的情况下可能不能出结果,那么在这样的严格模式下,必须指定输出的条
数。

sort by

 Hive中指定了sort by,那么在每个reducer端都会做排序,也就是说保证了局部有序(每个
 reducer出来的数据是有序的,但是不能保证所有的数据是有序的,除非只有一个reducer),好
 处是:执行了局部排序之后可以为接下去的全局排序提高不少的效率(其实就是做一次归并排序就
 可以做到全局排序了)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值