8、Hive的分區和分桶詳解

首先咱們先創建一個數據庫:sql

create database if not exists myhive1;數據庫

使用該數據庫:
use myhive1;app

若是存在該數據庫表student就刪除:
drop table if exists student;oop

建立數據庫表student並建立分區:
create table student(id int, name string, sex string ,age int, department string) row format delimited fields terminated by ",";測試

把文件中的數據寫入到student表中:
load data local inpath "/home/hadoop/student.txt" into table student;spa

查看student表裏的內容:
select * from student;
 code

1、分區

    hive表就是hdfs的上的一個目錄
    hive表中的數據,其實就是對應了HDFS上的一個目錄下的數據
    概念:對hive表的數據作分區管理orm

建立分區表:排序

建立分區表
    create table student_ptn(id int, name string) partitioned by (age int, department string) row format delimited fields terminated by ",";
    
    添加分區
    // 添加一個分區
    alter table student_ptn add partition(age=44,department="AA");
    // 一次添加多個分區
    alter table student_ptn add partition(age=66,department="CC") partition(age=55,department="BB");
    // 添加成功。可是分區字段的順序是在建立分區表的時候決定的
    alter table student_ptn add partition(department="DD",age=77); 
    // 添加分區時,指定分區的數據存儲目錄
    alter table student_ptn add partition(age=88,department="EE") location "/ptn_input1" partition(age=99,department="FF") location "/ptn_input2";

    查詢分區
    show partitions student_ptn;

    修改分區
    alter table student_ptn partition(age=44,department="AA") set location "hdfs://hadoop02:9000/ptn_input3";

    // 往某個特定的分區導入數據
    load data local inpath "/home/hadoop/student.txt" into table student_ptn partition(age=55,department="BB");

    load data local inpath "/home/hadoop/student.txt" into table student_ptn;  XXXXX  不能直接往分區表導入數據

    // 刪除分區
    alter table student_ptn drop partition(age=44,department="AA");  
    // 刪除分區的時候,包括分區的元數據信息和分區的數據及目錄
    // 清空分區表的時候,分區還在,數據被清空

    導入數據,大致上說,總共有三種方式:
    一、hadoop fs 
    二、load 
    三、insert ....select....

    // 使用insert....values... 的方法是導入數據,主要用於測試
    insert into table student_ptn values (101,"liutao");
    insert into table student_ptn partition(age=66,department="CC") values (101,"liutao");

    // 使用單重或者多重模式進去插入
    from student
    insert ... select ....
    insert ... select ....

    from student 
    insert into table student_ptn partition(age=18,department="A") select id,name where age = 18 
    insert into table student_ptn partition(age=18,department="B") select id,name where age = 19;

    // 驗證多重分區的插入是否成功
    select id, name from student_ptn where age = 18 and department  = "A";
    select id, name from student_ptn where age = 18 and department  = "B";

    // 動態分區
    set hive.exec.dynamic.partition = true;
    set hive.exec.dynamic.partition.mode = nonstrict;

    drop table student_ptn;

    insert into table student_ptn partition(age=101, department) select id, department, name from student;     XXXXXX
    insert into table student_ptn partition(age=202, department) select id, name, department from student;    √√√√√√√ 

    insert into table student_ptn(age) select id, name, age from student;

    動態分區的效果:

    按照動態分區的字段的值作劃分,一個值就是一個分區
    該studnet表當中的分區字段department有多少個值,就有多少個分區

    每一個分區就存一個分區字段值的全部數據

    department = IS  CS   MA

2、分桶hadoop

    概念:對分區的進一步的 更細粒度的劃分。 分區相似

    分桶的核心思想跟 MR程序的默認分區組件HashParititioner的原理一致
    原理:根據key的hash值去模除以reduceTask的個數/mapreduce的分區個數/hive表的分桶個數

    分桶的原理:對分桶字段的值進行hash,而後模除以桶的個數,獲得一個餘數,該餘數就是分桶的編號000000_0

    MR    分區    mapper的outKey    reduceTask的個數
    hive    分桶    分桶字段的值    分桶的個數

    分桶的效果:
    分桶字段的值通過分桶邏輯計算以後獲得的餘數相同的都在同一個分桶文件中

    一個分桶文件可能存在分桶字段的多個值
    一個分桶文件也可能存在沒有任何數據

    AA BB CC DD EE
    分桶的個數:3
    AA=0
    BB=1
    CC=0
    DD=1
    EE=0
    上面的AA和CC和EE都會出如今第一個分桶文件當中
    上面的BB和DD都會出如今第二個分桶文件中
    第三個分桶文件當中就不會出現任何值。

    表現形式上:
    若是沒有分區,那麼分桶的目錄就是表目錄的下一級
    若是有分區,那麼分桶的目錄在分區目錄的下一級
 

分桶的操做:

    建立分桶表:
    create table student_bucket (id int, name string, sex string, age int, department string) clustered by (age) sorted by(age desc, id asc) into 2 buckets row format delimited fields terminated by ",";

    往分桶表導入數據:
    load data local inpath "/home/hadoop/student.txt" into table student_bucket;
    注意:往分桶表導入數據,不能使用load方式   XXXXXXXXXXXX

    insert .... values ....
    insert into table student_bucket values (101,"liuyifei","female",22,"NVSHEN");
    insert into table student_bucket values (102,"luoyufeng","female",33,"nvdiaosi");
    // insert ....values...     XXXXXXXXXXXX

    // insert into .... select.....
    // XXXXXXXXXXXX
    insert into table student_bucket select id,name,sex,age,department from student;
    

    √√√√√√√√√√√√√√√√√√√√√√√√
    //  使用注意:打開分桶的開關,設置對應的reduceTask的個數要跟桶數匹配
    set hive.enforce.bucketing = true;
    set mapred.reduce.tasks = 2; / set mapreduce.job.reduces = 2;
    insert into table student_bucket select id,name,sex,age,department from student distribute by age sort by age desc, id asc;
    √√√√√√√√√√√√√√√√√√√√√√√√

    
    分桶的特例:
    create table student_bucket1 (id int, name string, sex string, age int, department string) clustered by (age) sorted by(age desc) into 2 buckets row format delimited fields terminated by ",";

    insert into table student_bucket1 select id,name,sex,age,department from student distribute by age;    XXXXXXXXXXXXX

    驗證的問題:最後分桶的數據到底有沒有排序、

    注意:建立分桶時指定的分桶和排序等等的信息都不能在數據插入的時候起做用
               數據到底有沒有分桶是根據插入數據的HQL語句決定
相關文章
相關標籤/搜索