在hive当中为什么要分区呢?就是要提高我们的查询速度,那么它是怎么提高查询速度的呢?首先,分区是指根据某个或几个字段来将数据表格切分成多个板块,根据你所指定的字段,这个字段里面有多少个值,我们就将分区建成多少个。所以,分区其实是在表这个单位下的下一个单位。因此,在HDFS上面分区也是一个目录。

所以分区字段是什么值这一批数据将落入到什么的分区目录下,不知道我这么解释小伙伴们能否很好的理解呢?

那么分区构建也有两种,分别是静态分区和动态分区。我们先来看看构建分区表的建表语法:

create table tab_name(col_name_1 data_type,col_name_2 data_type,......) partitioned by (col_name_partition data_type) row format delimited fields terminated by '...';

 这里我们需要明确的是,你的分区字段是不能出现在表结构字段里面的,这是一定一定要记得的。

当我们已经构建好了,我们需要把数据加载到表里面了吧。之前我们使用的加载数据是使用语法:load data [local] inpath '....' [overwrite] into table tab_name,如果是分区表的话,就在后面再加上 partition (col_name_partition = col_value ...),分区字段可以是多个的。这样你所要加载的数据将全部进入到这个分布目录当中,在HDFS上面也同时在表所对应的目录下生成一个分区目录,里面将放置你的数据。

但这种方法不好的地方是,如果我希望我是按照表数据里的某个以存在的字段来构建分区字段的话,那么怎么办呀?这个时候的数据也没哟scheme这个鬼,只能将全部数据加载到一个分区中,这个分区字段还不能出现在表字段当中。

这个时候我们可以先为我们的数据构建一个表结构,我们再创建一个分区表来重新加载这些数据。创建分区表的语法格式和上面一样。只是这个时候我们希望使用数据中某列作为分区字段,那么在构建表结构的时候就不要再写入这个列的字段名称了。

然后我们使用insert into table tab_name_1 partition (col_name_partition = col_value) select col_name_1,.... from tab_name where col_name_partition = col_value;这样就可以将特定的分区字段值的数据放入到专门的分区表当中了。在这里select后面的字段是不能出现将用于充当分区字段的原表字段的。

以上的这个方法是按照不同的值一个一个地手动输入的,如果分区字段有1000个值,或者我们有多个分区字段某每一个分区字段都有多个值,那么我们手动输入还不累死,这个在工作当中我们所要付出的代价就是加班。

所以hive也提供了一种动态分区的导入数据的方法。  insert into table tab_name_1 partition (col_name_partition) select col_name_1,.....,col_name_partition from tab_name;  这里分区字段是要出现在select的后面的,而且是所有字段的最后面,而前面的partition里面的字段就不指定具体的值了,这样当导入数据的时候系统将自动计算有多少个分区要建立了。

下面是一个简单的例子:

create table table_1(id int,name string,age int) row format delimited fields terminated by '\t';

这里我们为数据构建一个表,我们的数据里面有id,name,age这三个字段。现在我们打算再为这个数据构建一个以age为分区字段的分区表,所以我们还要重新创建一个分区表并以动态分区导入数据。

create table table_2(id int,name string) partitioned by(age int) row format delimited fields terminated by '\t';

isnert into table table_2 partition(age) select id,name,age from table_1;

注意分区字段age我是放在select的最后面的,虽然它本来就是在最后面的。

如果我们要使用静态导入的话,假设我们的age有三个值,分别是10,20,30。那么我们就要这样构建了:

insert into table table_2 partition(age=10) select id,name from table_1 where age=10;
insert into table table_2 partition(age=20) select id,name from table_1 where age=20;
insert into table table_2 partition(age=30) select id,name from table_1 where age=30;

这样根据分区字段值一个一个导入,同时在select里面是不能出现作为分区字段的那个字段的。

如果你们想在原来的基础上在添加一个新的分区目录,可以直接在HDFS上面mkdir -p一个新的分区目录,但目录名称要按格式来定义,然后在hive这里使用语法:alter table table_2 add partition (col_name_partition = col_value_new),如果前面没有mkdir -p手动添加目录的话就在后面继续些上location '....' 指定的路径吧。