• Hive分区(静态分区+动态分区)


            Hive分区的概念与传统关系型数据库分区不一样。   

            传统数据库的分区方式:就oracle而言,分区独立存在于段里,里面存储真实的数据,在数据进行插入的时候自动分配分区。   

            Hive的分区方式:因为Hive实际是存储在HDFS上的抽象,Hive的一个分区名对应一个目录名,子分区名就是子目录名,并非一个实际字段。

      因此能够这样理解,当在插入数据的时候指定分区,其实就是新建一个目录或者子目录,或者在原有的目录上添加数据文件。

    目录

    Hive分区的建立

    静态分区

    动态分区


     

    Hive分区的建立

      Hive分区是在建立表的时候用Partitioned by 关键字定义的,但要注意,Partitioned by子句中定义的列是表中正式的列,可是Hive下的数据文件中并不包含这些列,由于它们是目录名。

    静态分区

      建立一张静态分区表par_tab,单个分区

    create table par_tab (name string,nation string) partitioned by (sex string) row format delimited fields terminated by ',';

      这时候经过desc查看的表结构以下性能

    1. hive> desc par_tab;
    2. OK
    3. name                   string                                      
    4. nation                 string                                      
    5. sex                     string                                      
    6.          
    7. # Partition Information          
    8. # col_name               data_type               comment            
    9.          
    10. sex                     string                                      
    11. Time taken: 0.038 seconds, Fetched: 8 row(s)

      准备本地数据文件par_tab.txt,内容 “名字/国籍”,将以性别(sex)做为分区

    1. jan,china
    2. mary,america
    3. lilei,china
    4. heyong,china
    5. yiku,japan
    6. emoji,japan

      把数据插入到表(其实load操做至关于把文件移动到HDFS的Hive目录下)

    load data local inpath '/home/hadoop/files/par_tab.txt' into table par_tab partition (sex='man');

      这时候在hive下查询par_tab表,变成了3列

    1. hive> select * from par_tab;
    2. OK
    3. jan   china   man
    4. mary   america   man
    5. lilei   china   man
    6. heyong   china   man
    7. yiku   japan   man
    8. emoji   japan   man
    9. Time taken: 0.076 seconds, Fetched: 6 row(s)

      查看par_tab目录结构

    [hadoop@hadoop001 files]$ hadoop dfs -lsr /user/hive/warehouse/par_tab ​ drwxr-xr-x   - hadoop supergroup         0 2017-03-29 08:25 /user/hive/warehouse/par_tab/sex=man -rwxr-xr-x   1 hadoop supergroup         71 2017-03-29 08:25 /user/hive/warehouse/par_tab/sex=man/par_tab.txt
    

      能够看到,在新建分区表的时候,系统会在hive数据仓库默认路径/user/hive/warehouse/下建立一个目录(表名),再建立目录的子目录sex=man(分区名),最后在分区名下存放实际的数据文件。

      若是再插入另外一个数据文件数据:

    1. lily,china
    2. nancy,china
    3. hanmeimei,america

      插入数据

    load data local inpath '/home/hadoop/files/par_tab_wm.txt' into table par_tab partition (sex='woman');

      查看par_tab表目录结构

    [hadoop@hadoop001 files]$ hadoop dfs -lsr /user/hive/warehouse/par_tab drwxr-xr-x   - hadoop supergroup         0 2017-03-29 08:25 /user/hive/warehouse/par_tab/sex=man -rwxr-xr-x   1 hadoop supergroup         71 2017-03-29 08:25 /user/hive/warehouse/par_tab/sex=man/par_tab.txt drwxr-xr-x   - hadoop supergroup         0 2017-03-29 08:35 /user/hive/warehouse/par_tab/sex=woman -rwxr-xr-x   1 hadoop supergroup         41 2017-03-29 08:35 /user/hive/warehouse/par_tab/sex=woman/par_tab_wm.txt
    

      最后查看两次插入的结果,包含了man和woman

    1. hive> select * from par_tab;
    2. OK
    3. jan   china   man
    4. mary   america   man
    5. lilei   china   man
    6. heyong   china   man
    7. yiku   japan   man
    8. emoji   japan   man
    9. lily   china   woman
    10. nancy   china   woman
    11. hanmeimei   america   woman
    12. Time taken: 0.136 seconds, Fetched: 9 row(s)

      由于分区列是表实际定义的列,因此查询分区数据时

    1. hive> select * from par_tab where sex='woman';
    2. OK
    3. lily   china   woman
    4. nancy   china   woman
    5. hanmeimei   america   woman
    6. Time taken: 0.515 seconds, Fetched: 3 row(s)

      下面建立一张静态分区表par_tab_muilt,多个分区(性别+日期)

    1. hive> create table par_tab_muilt (name string, nation string) partitioned by (sex string,dt string) row format delimited fields terminated by ',' ;
    2. hive> load data local inpath '/home/hadoop/files/par_tab.txt' into table par_tab_muilt partition (sex='man',dt='2017-03-29');
    ​
    [hadoop@hadoop001 files]$ hadoop dfs -lsr /user/hive/warehouse/par_tab_muilt drwxr-xr-x   - hadoop supergroup         0 2017-03-29 08:45 /user/hive/warehouse/par_tab_muilt/sex=man drwxr-xr-x   - hadoop supergroup         0 2017-03-29 08:45 /user/hive/warehouse/par_tab_muilt/sex=man/dt=2017-03-29 -rwxr-xr-x   1 hadoop supergroup         71 2017-03-29 08:45 /user/hive/warehouse/par_tab_muilt/sex=man/dt=2017-03-29/par_tab.txt

      可见,新建表的时候定义的分区顺序,决定了文件目录顺序(谁是父目录谁是子目录),正由于有了这个层级关系,当查询全部man的时候,man如下的全部日期下的数据都会被查出来。若是只查询日期分区,但父目录sex=man和sex=woman都有该日期的数据,那么Hive会对输入路径进行修剪,从而只扫描日期分区性别分区不做过滤(即查询结果包含了全部性别)。

     

    动态分区

      若是用上述的静态分区,插入的时候必须首先要知道有什么分区类型,并且每一个分区写一个load data,比较麻烦。使用动态分区可解决以上问题,其能够根据查询获得的数据动态分配到分区里。其实动态分区与静态分区区别就是不指定分区目录,由系统本身选择。

      首先,启动动态分区功能

    hive> set hive.exec.dynamic.partition=true;

      假设已有一张表par_tab,前两列是名称name和国籍nation,后两列是分区列,性别sex和日期dt,数据以下

    1. hive> select * from par_tab;
    2. OK
    3. lily   china   man   2013-03-28
    4. nancy   china   man   2013-03-28
    5. hanmeimei   america   man   2013-03-28
    6. jan   china   man   2013-03-29
    7. mary   america   man   2013-03-29
    8. lilei   china   man   2013-03-29
    9. heyong   china   man   2013-03-29
    10. yiku   japan   man   2013-03-29
    11. emoji   japan   man   2013-03-29
    12. Time taken: 1.141 seconds, Fetched: 9 row(s)

      我把这张表的内容直接插入到另外一张表par_dnm中,并实现sex为静态分区,dt动态分区(不指定究竟是哪日,让系统本身分配决定)

    1. hive> insert overwrite table par_dnm partition(sex='man',dt)
    2.   > select name, nation, dt from par_tab;

      插入后看下目录结构

    drwxr-xr-x   - hadoop supergroup         0 2017-03-29 10:32 /user/hive/warehouse/par_dnm/sex=man drwxr-xr-x   - hadoop supergroup         0 2017-03-29 10:32 /user/hive/warehouse/par_dnm/sex=man/dt=2013-03-28 -rwxr-xr-x   1 hadoop supergroup         41 2017-03-29 10:32 /user/hive/warehouse/par_dnm/sex=man/dt=2013-03-28/000000_0 drwxr-xr-x   - hadoop supergroup         0 2017-03-29 10:32 /user/hive/warehouse/par_dnm/sex=man/dt=2013-03-29 -rwxr-xr-x   1 hadoop supergroup         71 2017-03-29 10:32 /user/hive/warehouse/par_dnm/sex=man/dt=2013-03-29/000000_0
    

      再查看分区数

    1. hive> show partitions par_dnm;
    2. OK
    3. sex=man/dt=2013-03-28
    4. sex=man/dt=2013-03-29
    5. Time taken: 0.065 seconds, Fetched: 2 row(s)

      证实动态分区成功。

      注意,动态分区不容许主分区采用动态列而副分区采用静态列,这样将致使全部的主分区都要建立副分区静态列所定义的分区。

      动态分区能够容许全部的分区列都是动态分区列,可是要首先设置一个参数hive.exec.dynamic.partition.mode :

    1. hive> set hive.exec.dynamic.partition.mode;
    2. hive.exec.dynamic.partition.mode=strict

      它的默认值是strict,即不容许分区列所有是动态的,这是为了防止用户有可能原意是只在子分区内进行动态建分区,可是因为疏忽忘记为主分区列指定值了,这将致使一个dml语句在短期内建立大量的新的分区(对应大量新的文件夹),对系统性能带来影响。 因此要设置:

    hive> set hive.exec.dynamic.partition.mode=nostrict;

  • 相关阅读:
    ardupilot BMI088加速度陀螺仪学习
    独立站FP收款黑科技来啦!再也不用担心账户被封了~
    【C语音 || 数据结构】二叉树--堆
    统计学习---第一章
    ts中的元组是什么有什么用
    【集群迁移】使用Shell脚本获取老集群整个Hive库的建库、建表DDL
    VulnHub1:Jangow: 1.0.1靶机学习
    Tomcat 正确安装并启动后,浏览器访问localhost8080显示404
    java高级:注解
    《七月集训》(第二天)——字符串
  • 原文地址:https://blog.csdn.net/m0_54925305/article/details/127488493