Hive 分区之静态与动态分区

hive 分区之动态静态分区

在这里插入图片描述

hive 分区

  • 单值分区

    静态分区: 分区值是确定的, 新增分区或者是加载分区数据时需要手动指定分区

    1. 静态分区创建

      语法: partition by ( 分区键 类型 , 分区键 类型 )

      注: 指定的分区键不能出现在定义的列名中

    2. 静态分区写入

      覆盖写入 --- overwrite
      	INSERT OVERWRITE TABLE <table_name> 
      	 PARTITION (<partition_key>=<partition_value>[,<partition_key>=<partition_value>, ...]) 
      	 SELECT <select_statement>;
      追加写入 --- into
      	INSERT INTO TABLE <table_name> 
      	.... 同上
      
    3. 添加分区

      //只能添加分区列的值,不能再添加分区列; 若是多个分区列,不能单独添加其中一个
      alter table tablename add partition(col=value)
      
    4. 删除分区

      //可以删除一个分区列,但是会把表中所有包含当前分区列的数据全部删除
      alter table tablename drop partition(col=value)
      
    5. 修复分区

      现象: 手动向hdfs中创建分区目录,添加数据,创建好hive的表之后,无法加载数据
      原因: 元数据中没有相应的记录
      执行后: Hive会检测如果HDFS目录下存在但表的metastore中不存在的partition元信息,更新到metastore中
      篇幅有限, 如果我讲的不是很清楚的话, 请移步大佬博客 https://blog.csdn.net/qq_21050291/article/details/73188666  两字概括: 清晰!
      msck repair table tablename
      

    动态分区: 分区值是不确定的, 由输入值动态判断目标分区

    1. 动态分区创建

      创建方式与静态分区表完全一样,一张表可同时被静态分区和动态分区键分区,只是动态分区键需要放在静态分区键的后面(HDFS上的动态分区目录下不能包含静态分区的子目录),如下spk即static partition key(静态分区键),dpk为dynamic partition key(动态分区键)

      CREATE TABLE <table_name>
       PARTITIONED BY ([<spk> <data_type>, ... ,] <dpk> <data_type>, [<dpk> <data_type>,...]);
      
    2. 动态分区写入

      根据表中的某一个列值来确定hdfs存储的目录:

      优点:

      ​ 动态可变,不需要人为控制。

      ​ 假如设定的是日期,那么每一天的数据会单独存储在一个文件夹中

      缺点:

      ​ 需要依靠MR完成,执行比较慢

      ​ 静态分区键要用 = 指定分区值;

      ​ 动态分区只需要给出分出分区键名称

      分区相关属性
      // 是否允许动态分区
      	set hive.exec.dynamic.partition=true;
      // 分区模式设置, strict:至少有一个是静态分区; nostrict:全部是动态分区
      	//set hive.exec.dynamic.partition.mode=nostrict;
      // 设置最大分区数
      	set hive.exec.max.dynamic.partitions=2000;
      // 单个节点上的mapper/reducer允许创建的最大分区
      	hive.exec.max.dynamic.partitions.pernode =100 :
      
      insert into table1 select 普通字段 分区字段 from table2
      
    3. 动态分区严格模式非严格模式

      创建方式与静态分区表完全一样
      1. 创建一个表添加分区规则
      	partitioned by(year int,month int,day int)
      2. 指定严格模式数据导入
      	set hive.exec.dynamic.partition.mode=strict;
      		严格模式: 至少有一个分区是静态分区,且动态分区在静态分区之后
      	insert into table dyp1 partition(year=2016,month,day)
      3. 指定非严格模式数据导入
      	set hive.exec.dynamic.partition.mode=nostrict;
      		非严格模式: 可以全部是动态分区
      	insert into table dyp2 partition(year,month,day)
      

    分区注意细节

  1. 尽量不要用动态分区,因为动态分区的时候,将会为每一个分区分配reducer数量,当分区数量多的时候,reducer数量将会增加,对服务器是一种灾难。

  2. 动态分区和静态分区的区别,静态分区不管有没有数据都将会创建该分区,动态分区是有结果集将创建,否则不创建。

  3. hive动态分区的 hive.exec.dynamic.partition.mode 严格模式(这种严格模式在上述操作已经解释)和 hive 提供的 hive.mapred.mode 的严格模式。

    ​ hive提供我们一个严格模式:为了阻止用户不小心提交恶意hql

    ​ hive.mapred.mode=nostrict : strict

    ​ 如果该模式值为strict,将会阻止以下三种查询:

       ​	1、对分区表查询,where中过滤字段不是分区字段。
    
      ​	2、笛卡尔积join查询,join查询语句,不带on条件或者where条件。
    
       ​	3、对order by查询,有order by的查询不带limit语句。
    
  • 范围分区

    • 单值分区每个分区对应于分区键的一个取值,而每个范围分区则对应分区键的一个区间,只要落在指定区间内的记录都被存储在对应的分区下。分区范围需要手动指定,分区的范围为前闭后开区间 [最小值, 最大值)。最后出现的分区可以使用 MAXVALUE 作为上限,MAXVALUE 代表该分区键的数据类型所允许的最大值

    • 多个范围分区键情况

      DROP TABLE IF EXISTS test_demo;
      CREATE TABLE test_demo (value INT)
      PARTITIONED BY RANGE (id1 INT, id2 INT, id3 INT)
      (
      -- id1在(--∞,5]之间,id2在(-∞,105]之间,id3在(-∞,205]之间
      PARTITION p5_105_205 VALUES LESS THAN (5, 105, 205),
      -- id1在(--∞,5]之间,id2在(-∞,105]之间,id3在(205,215]之间
      PARTITION p5_105_215 VALUES LESS THAN (5, 105, 215),
      PARTITION pall_max values less than (MAXVALUE, MAXVALUE, MAXVALUE)
      );
      
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值