温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Hive分区表的分区操作方法

发布时间:2021-08-24 12:02:17 来源:亿速云 阅读:839 作者:chen 栏目:大数据

本篇内容主要讲解“Hive分区表的分区操作方法”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Hive分区表的分区操作方法”吧!

Hive 没有行级别的数据的增删改,往表中装载数据唯一途径就是 使用大量数据进行装载,可以通过load 可以 insert

动态分区 ,动态静态

所以hive提供了一个动态分区功能,其可以基于查询参数的位置去推断分区的名称,从而建立分区

注意:使用,insert...select 往表中导入数据时,查询的字段个数必须和目标的字段个数相同,不能多,也不能少,否则会报错。但是如果字段的类型不一致的话,则会使用null值填充,不会报错。而使用load data形式往hive表中装载数据时,则不会检查。如果字段多了则会丢弃,少了则会null值填充。同样如果字段类型不一致,也是使用null值填充。
多个分区字段时,实现半自动分区(部分字段静态分区,注意静态分区字段要在动态前面)

为了对表进行合理的管理以及提高查询效率,Hive可以将表组织成“分区”。一个分区实际上就是表下的一个目录,一个表可以在多个维度上进行分区,分区之间的关系就是目录树的关系。

1、创建分区表
通过 PARTITIONED BY 子句指定,分区的顺序决定了谁是父目录,谁是子目录。
创建有一个分区的分区表:

CREATE TABLE IF NOT EXISTS part_test(         
  c1       string
 ,c2       string
 ,c3       string 
 ,c4       string
)PARTITIONED BY (day_id string)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '|'
STORED AS TEXTFILE;


创建有两个分区的分区表:

CREATE TABLE IF NOT EXISTS part_test_1(                
  c1       string
 ,c2       string   
 ,c3       string 
 ,c4       string   
) PARTITIONED BY (month_id string,day_id string)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '|'
STORED AS TEXTFILE;

2、    外部分区表
外部表也可以建成分区表,如hdfs目录/user/tuoming/part下有

201805和201806两个目录,201805下有一个20180509子目录,201806下有20180609和20180610两个子目录。

创建一个映射到/user/tuoming/part目录的外部分区表:

CREATE EXTERNAL TABLE IF NOT EXISTS part_test_2(
  c1       string
 ,c2       string
 ,c3       string
 ,c4       string
)PARTITIONED BY (month_id string,day_id string)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
STORED AS TEXTFILE

LOCATION '/user/tuoming/part';为part_test_2增加分区:

alter table part_test_2 add partition(month_id='201805',day_id='20180509') location '/user/tuoming/part/201805/20180509';


alter table part_test_2 add partition(month_id='201806',day_id='20180609') location '/user/tuoming/part/201806/20180609';


alter table part_test_2 add partition(month_id='201806',day_id='20180610') location '/user/tuoming/part/201806/20180610';

使用show partitions语句查看part_test_2有哪些分区:
show partitions part_test_2;3、    内部分区表
创建一个主分区为month_id,子分区为day_id的内部分区表:

CREATE TABLE IF NOT EXISTS part_test_3(                
  c1       string
 ,c2       string   
 ,c3       string 
 ,c4       string   
)PARTITIONED BY (month_id string,day_id string)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '|'

STORED AS TEXTFILE;

为内部分区表加载数据
(1)使用load data inpath…overwrite into table partition语句从hdfs目录加载:

load data inpath '/user/tuoming/test/test' overwrite into table part_test_3 partition(month_id='201805',day_id='20180509');

数据内容如下:

(2)使用insert overwrite table/ insert into…partition语句从查询结果中加载:
覆盖插入:

insert overwrite table part_test_3 partition(month_id='201805',day_id='20180509') select * from part_test_temp;

追加插入:

insert into part_test_3 partition(month_id='201805',day_id='20180509') select * from part_test_temp;

注意:使用以上两种方法为内部分区表加载数据不需要预创建分区,加载数据时会自动创建相应的分区。如果想要为内部表预先创建分区,需要使用hadoop fs  –mkdir命令在表目录下先创建相应的分区目录,然后再使用alter table add partition语句增加分区:

4、    删除分区
使用alter table…drop partition语句删除对应分区:

alter table part_test_3 drop partition(day_id='20180509');

注意:外部分区表使用alter table…drop partition语句删除分区,只会删除元数据,相应的目录和文件并不会删除。内部表使用该语句删除分区,既会删除元数据,也会删除相应的目录和数据文件。

5、    动态分区
上述使用insert overwrite table…partition…从查询结果加载数据到分区,必须指定特定的分区,而且每个分区都需要使用一条插入语句。当需要一次插入多个分区的数据时,可以使用动态分区,根据查询得到的数据动态分配到分区里。动态分区与静态分区的区别就是不指定分区目录,由hive根据实际的数据选择插入到哪一个分区。

#启动动态分区功能
set hive.exec.dynamic.partition=true;  
#允许全部分区都是动态分区
set hive.exec.dynamic.partition.mode=nostrick;

#month_id为静态分区,day_id为动态分区:

insert overwrite table dynamic_test partition(month_id='201710',day_id)  
select c1,c2,c3,c4,c5,c6,c7,day_id from kafka_offset
where substr(day_id,1,6)='201710';

# month_id和 day_id均为动态分区:

insert overwrite table dynamic_test partition(month_id,day_id)  
select c1,c2,c3,c4,c5,c6,c7,substr(day_id,1,6) as month_id,day_id from kafka_offset;

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

insert overwrite table dynamic_test partition(month_id,day_id)
select c1,c2,c3,c4,c5,c6,c7,substr(day_id,1,6) as month_id,day_id from kafka_offset
distribute by month_id,day_id;

Hive分区表的分区操作方法

Hive中的几种不同的数据导出方式。可以根据导出的地方不一样,将这些方式分为三种:

  • 导出到本地文件系统;

  • 导出到HDFS中;

  • 导出到Hive的另一个表中。

为了避免单纯的文字,我将一步一步地用命令进行说明。

文章目录

  • 1 导出到本地文件系统

  • 2 导出到HDFS中

  • 3 导出到Hive的另一个表中

导出到本地文件系统

hive> insert overwrite local directory '/home/wyp/wyp' select * from wyp;

这条HQL的执行需要启用Mapreduce完成,运行完这条语句之后,将会在本地文件系统的/home/wyp/wyp目录下生成文件,这个文件是Reduce产生的结果(这里生成的文件名是000000_0),我们可以看看这个文件的内容:

[wyp@master ~/wyp]$ vim 000000_0

5^Awyp1^A23^A131212121212

6^Awyp2^A24^A134535353535

7^Awyp3^A25^A132453535353

8^Awyp4^A26^A154243434355

1^Awyp^A25^A13188888888888

2^Atest^A30^A13888888888888

3^Azs^A34^A899314121


和导入数据到Hive不一样,不能用 insert into 来将数据导出:可以看出,这就是wyp表中的所有数据。数据中的列与列之间的分隔符是 ^A (ascii码是 \00001 )。

导出到HDFS中

和导入数据到本地文件系统一样的简单,可以用下面的语句实现:

hive> insert overwrite directory '/home/wyp/hdfs' select * from wyp;

将会在HDFS的 /home/wyp/hdfs 目录下保存导出来的数据。注意,和导出文件到本地文件系统的HQL少一个local,数据的存放路径就不一样了。

导出到Hive的另一个表中

其实这个在《Hive几种数据导入方式》文中就用到了,这也是Hive的数据导入方式,如下操作:

hive> insert into table test

    > partition (age='25')

    > select id, name, tel

    > from wyp;

#####################################################################

           这里输出了一堆Mapreduce任务信息,这里省略

#####################################################################

Total MapReduce CPU Time Spent: 1 seconds 310 msec

OK

Time taken: 19.125 seconds

hive> select * from test;

OK

5       wyp1    131212121212    25

6       wyp2    134535353535    25

7       wyp3    132453535353    25

8       wyp4    154243434355    25

1       wyp     13188888888888  25

2       test    13888888888888  25

3       zs      899314121       25

Time taken: 0.126 seconds, Fetched: 7 row(s)


如果你用的Hive版本是0.11.0,那么你可以在导出数据的时候来指定列之间的分隔符(可以参见本博客的《Hive0.11查询结果保存到文件并指定列之间的分隔符》),操作如下:细心的读者可能会问,怎么导入数据到文件中,数据的列之间为什么不是wyp表设定的列分隔符呢?其实在Hive 0.11.0版本之间,数据的导出是不能指定列之间的分隔符的,只能用默认的列分隔符,也就是上面的^A来分割,这样导出来的数据很不直观,看起来很不方便!

hive> insert overwrite local directory '/home/iteblog/local'

    > row format delimited

    > fields terminated by '\t'

    select from wyp;

 

[wyp@master ~/local]$ vim 000000_0

5       wyp1    23      131212121212

6       wyp2    24      134535353535

7       wyp3    25      132453535353

8       wyp4    26      154243434355

1       wyp     25      13188888888888

2       test    30      13888888888888

3       zs      34      899314121

这个很不错吧!

其实,我们还可以用hive的 -e 和 -f 参数来导出数据。其中-e 表示后面直接接带双引号的sql语句;而-f是接一个文件,文件的内容为一个sql语句,如下:

  

[wyp@master ~/local]$  hive -e "select * from wyp" >> local/wyp.txt

[wyp@master ~/local]$  cat wyp.txt

5       wyp1    23      131212121212

6       wyp2    24      134535353535

7       wyp3    25      132453535353

8       wyp4    26      154243434355

1       wyp     25      13188888888888

2       test    30      13888888888888

3       zs      34      899314121
[wyp@master ~/local]$ cat wyp.sql

select * from wyp

[wyp@master ~/local]$ hive -f wyp.sql >> local/wyp2.txt

得到的结果也是用 \t 分割的。也可以用-f参数实现:

上述语句得到的结果也是 \t 分割的。

到此,相信大家对“Hive分区表的分区操作方法”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI