Hive 静态分区和动态分区详解

1.分区表
    分区表实际上就是对应一个HDFS文件系统上的独立的文件夹,该文件夹下是该分区所有的数据文件。 Hive中的分区就是分目录,把一个大的数据集根据业务需要分割成小的数据集。在查询时通过WHERE子句中的表达式选择查询所需要的指定的分区,这样的查询效率会提高很多。
1.1 分区表基本操作
1.1.1 创建分区表语法(需要根据日期对日志进行管理)
hive (default)> create table dept_partition(
                deptno int, 
                dname string, 
                loc string
               )
               partitioned by (month string)
               row format delimited fields terminated by '\t';

1.1.2 加载数据到分区表中

hive (default)> load data local inpath '/opt/module/datas/dept.txt' into table default.dept_partition partition(month='201805');
hive (default)> load data local inpath '/opt/module/datas/dept.txt' into table default.dept_partition partition(month='201806');
hive (default)> load data local inpath '/opt/module/datas/dept.txt' into table default.dept_partition partition(month='201807’);
hive (default)> load data local inpath '/opt/module/datas/dept.txt' into table default.dept_partition partition(month='201808’);

1.1.3 加载数据到分区表  

Hive 静态分区和动态分区详解_第1张图片1.1.4 查询分区表中数据

// 单分区查询
 hive (default)> select * from dept_partition where month='201805';

// 多分区联合查询
hive (default)>  select * from dept_partition where month='201805'
              >     union
              >  select * from dept_partition where month='201806'
              >     union
              >  select * from dept_partition where month='201807’;

_u3.deptno    _u3.dname    _u3.loc    _u3.month
10    ACCOUNTING    1700    201805
10    ACCOUNTING    1700    201806
10    ACCOUNTING    1700    201807
20    RESEARCH    1800    201805
20    RESEARCH    1800    201806
20    RESEARCH    1800    201807
30    SALES    1900    201805
30    SALES    1900    201806
30    SALES    1900    201807
40    OPERATIONS    1700    201805
40    OPERATIONS    1700    201806
40    OPERATIONS    1700    201807
 
1.1.5 增加分区
// 创建单个分区
hive (default)> alter table dept_partition add partition(month='201809') ;

//同时创建多个分区
hive (default)> alter table dept_partition add partition(month='201810') partition(month='201811');

1.1.6 删除分区


// 删除单个分区
hive (default)> alter table dept_partition drop partition (month='201809’);

// 同时删除多个分区
hive (default)> alter table dept_partition drop partition (month='201810'), partition (month='201811');

1.1.7 查看分区表有多少分区


hive> show partitions dept_partition;

1.1.8 查看分区表结构


hive (default)> desc formatted dept_partition;
OK
col_name    data_type    comment
# col_name                data_type               comment

deptno                  string
dname                   string
loc                     string

# Partition Information
# col_name                data_type               comment

month                   string

1.2 分区表注意事项

1.2.1 创建二级分区表

hive (default)>  create table dept_partition2(
              >                deptno int, dname string, loc string
              >                )
              >                partitioned by (month string, day string)
              >                row format delimited fields terminated by '\t';
OK
Time taken: 0.094 seconds
 
1.2.2 正常的加载数据
    • 加载数据到二级分区表中
        hive (default)> load data local inpath '/opt/module/datas/dept.txt' into table default.dept_partition2 partition(month='201709', day='13');
    • 查询分区数据
        hive (default)> select * from dept_partition2 where month='201709' and day='13’;
    • 把数据直接上传到分区目录上,让分区表和数据产生关联的三种方式
方式一:上传数据后修复
    上传数据
        hive (default)> dfs -mkdir -p /user/hive/warehouse/dept_partition2/month=201709/day=12;
        hive (default)> dfs -put /opt/module/datas/dept.txt  /user/hive/warehouse/dept_partition2/month=201709/day=12;
    查询数据(查询不到刚上传的数据)
        hive (default)> select * from dept_partition2 where month='201709' and day='12';
执行修复命令
        hive> msck repair table dept_partition2;
再次查询数据
        hive (default)> select * from dept_partition2 where month='201709' and day='12';
方式二:上传数据后添加分区
    上传数据
        hive (default)> dfs -mkdir -p /user/hive/warehouse/dept_partition2/month=201709/day=11;
        hive (default)> dfs -put /opt/module/datas/dept.txt  /user/hive/warehouse/dept_partition2/month=201709/day=11;
    执行添加分区
        hive (default)> alter table dept_partition2 add partition(month='201709',day='11');
    查询数据
        hive (default)> select * from dept_partition2 where month='201709' and day='11';
方式三:上传数据后load数据到分区
    创建目录
        hive (default)> dfs -mkdir -p /user/hive/warehouse/dept_partition2/month=201709/day=10;
    上传数据
        hive (default)> load data local inpath '/opt/module/datas/dept.txt' into table dept_partition2 partition(month='201709',day='10');
    查询数据
        hive (default)> select * from dept_partition2 where month='201709' and day='10';
 
2.动态分区
  往hive分区表中插入数据时,如果需要创建的分区很多,比如以表中某个字段进行分区存储,则需要复制粘贴修改很多sql去执行,效率低。因为hive是批处理系统,所以hive提供了一个动态分区功能,其可以基于查询参数的位置去推断分区的名称,从而建立分区。
2.1 创建一个单一字段分区表
hive>create table dpartition(id int ,name string) partitioned by(ct string);

2.2 往表里装载数据,并且动态建立分区,以city建立动态分区

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


insert overwrite table dpartition partition(ct) select id ,name,city from  mytest_tmp2_p;

要点:因为dpartition表中只有两个字段,所以当我们查询了三个字段时(多了city字段),所以系统默认以最后一个字段city为分区名,因为分区表的分区字段默认也是该表中的字段,且依次排在表中字段的最后面。所以分区需要分区的字段只能放在后面,不能把顺序弄错。如果我们查询了四个字段的话,则会报错,因为该表加上分区字段也才三个。要注意系统是根据查询字段的位置推断分区名的,而不是字段名称。

hive>
 set hive.exec.dynamici.partition=true;
 set hive.exec.dynamic.partition.mode=nonstrict;
 insert overwrite table ds_parttion
 partition(state='china',ct)  #state分区为静态,ct为动态分区,以查询的city字段为分区名
 select id ,city from  mytest_tmp2_p; 

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

 
2.3 多个分区字段时,实现半自动分区(部分字段静态分区,注意静态分区字段要在动态前面)
2.3.1 创建一个只有一个字段,两个分区字段的分区表
hive (fdm_sor)> create table ds_parttion(id int ) partitioned by (state string ,ct string );

2.3.2 往该分区表半动态分区插入数据

hive>
 set hive.exec.dynamici.partition=true;
 set hive.exec.dynamic.partition.mode=nonstrict;
 insert overwrite table ds_parttion
 partition(state='china',ct)  #state分区为静态,ct为动态分区,以查询的city字段为分区名
 select id ,city from  mytest_tmp2_p; 
2.3.3 查询结果显示:
hive (fdm_sor)> select *  from ds_parttion where state='china' ;
ds_parttion.id  ds_parttion.state       ds_parttion.ct
4       china   beijing
3       china   beijing
2       china   beijing
1       china   beijing
4       china   beijing1
3       china   beijing1
2       china   beijing1
1       china   beijing1


hive (fdm_sor)> select *  from ds_parttion where state='china' and ct='beijing';
ds_parttion.id  ds_parttion.state       ds_parttion.ct
4       china   beijing
3       china   beijing
2       china   beijing
1       china   beijing


hive (fdm_sor)> select *  from ds_parttion where state='china' and ct='beijing1';
ds_parttion.id  ds_parttion.state       ds_parttion.ct
4       china   beijing1
3       china   beijing1
2       china   beijing1
1       china   beijing1
Time taken: 0.072 seconds, Fetched: 4 row(s)
 
2.3.4 多个分区字段时,全部实现动态分区插入数据
set hive.exec.dynamici.partition=true;
set hive.exec.dynamic.partition.mode=nonstrict;
insert overwrite table ds_parttion partition(state,ct) select id ,country,city from  mytest_tmp2_p;

注意:字段的个数和顺序不能弄错。


2.3.5 动态分区表的属性

1.使用动态分区表必须配置的参数 :
    set hive.exec.dynamic.partition =true(默认false),表示开启动态分区功能
    set hive.exec.dynamic.partition.mode = nonstrict(默认strict),表示允许所有分区都是动态的,否则必须有静态分区字段


2.动态分区相关的调优参数:
    set  hive.exec.max.dynamic.partitions.pernode=100 (默认100,一般可以设置大一点,比如1000)
       表示每个maper或reducer可以允许创建的最大动态分区个数,默认是100,超出则会报错。


   set hive.exec.max.dynamic.partitions =1000(默认值)
       表示一个动态分区语句可以创建的最大动态分区个数,超出报错


   set hive.exec.max.created.files =10000(默认) 全局可以创建的最大文件个数,超出报错。
 

你可能感兴趣的:(#,Hive)