hive分區表和分桶表


先創建一個數據庫myhive2019
create database if not exists myhive2019;

在myhive2019數據庫下創建內部表 student:
create table student(id int,name string,gender string,age int,department string) row format delimited fields terminated by “,”;

導入數據:
load data local inpath “/home/hadoopUser/students.txt” into table student;
在這裏插入圖片描述

1.分區表

分區是在該表的目錄下創建多個文件夾分別存儲數據。

關鍵語法:partitioned by

1.1靜態分區

  1. 創建分區表 student_ptn:
    create table student_ptn(id int,name string,age int,department string)
    partitioned by(gender string)
    row format delimited fields terminated by “,”;

    注意:分區字段不能與表字段重複。

  2. 創建分區表後,可以通過show partitions student_ptn;查看是否有分區定義,剛創建出來一般是沒有的。
    在這裏插入圖片描述

  3. 通過alter語法添加一個或多個分區定義(該例子以性別作爲分區):
    alter table student_ptn add partition(gender=‘male’);
    alter table student_ptn add partition(gender=‘female’);
    在這裏插入圖片描述
    對應地,在HDFS上也能看見創建的分區文件夾,d代表文件夾。
    在這裏插入圖片描述

  4. 往分區表中的分區文件夾下導入數據:
    導入數據的方式可查看這篇文章:hive數據導入的6種方式

    這裏主要介紹2種插入方法:
    1)insert…values… (一般是用作測試)
    insert into table student_ptn partition(gender=‘male’) values(1,“小明”,18,“MA”);

    2)//單重或多重插入
    from 數據表
    insert…select…

    //單重插入
    from student
    insert into table student_ptn partition(gender=“male”) select id,name,age,department where gender = “男”;

    //多重插入,insert之間不用逗號分隔
    from student
    insert into table student_ptn partition(gender=‘male’) select id,name,age,department where gender=“男”
    insert into table student_ptn partition(gender=‘female’) select id,name,age,department where gender=“女”;

    //查詢是否插入成功
    select * from student_ptn where gender = “male”;
    在這裏插入圖片描述在這裏插入圖片描述
    注意:不能直接往分區表中導入數據。
    在這裏插入圖片描述

  5. 修改分區
    alter table 分區表 partiton(分區字段) set location “HDFS路徑”;

  6. 刪除分區
    包括分區的元數據信息和分區的數據及目錄。
    alter table 分區表 drop partition(分區字段) ;

  7. 清空分區
    清空分區內所有數據文件,但是該分區文件夾還在。
    truncate table 分區表 partition(分區字段);

    若只想刪除該分區下的部分數據文件,使用hadoop命令刪除。
    hadoop fs -rm -f hive數據存儲的路徑/數據文件名

小結

  1. 分區字段不能和表字段重複。
  2. 通過show partitions 分區表 可以查看該分區表是否有分區定義。
  3. 分區定義可以一個字段或者多個字段。
  4. 通過alter table 分區表 add partition(分區字段1 = XXX,分區字段2 = XXX…);來添加分區定義。(分區字段的個數和順序需要在創建分區表時指定好)
  5. 分區表不能直接插入數據,分區表中的任何數據一定要屬於某個分區(比如任何一箇中國人,都必須屬於某個省)。

最大的作用:

  1. 在select的時候,可以通過where來過濾條件,提升效率。
    舉例:
    select * from student_ptn where gender = “male”;
    解釋:
    如果student_ptn 是普通表,sql會進行全表掃描。
    如果student_ptn 是分區表,並且剛好gender是分區字段,只需要掃描這個分區表中的 gender=“male” 這個文件中的數據即可,避免了全表掃描。

應用場景:

  1. 當某份數據中的某個字段經常被用來進行where過濾,那麼該表最好被創建成分區表,並把過濾條件的字段定義爲分區字段。

1.2動態分區

1.2.1單字段動態分區

如果student表的age字段需要做分區字段,創建靜態分區需要手動創建很多個,非常重複性勞動。所以hive提供了動態分區功能,能夠根據你的分區字段有多少個值,自動創建多少個分區。

  1. 創建分區表 student_age(和靜態分區一樣)

    create table student_age(id int,name string,gender string)
    partitioned by(age int)
    row format delimited fields terminated by “,”;

  2. 動態分區參數設置,最好手動開啓
    1)查看開關
    語法:set 開關
    set hive.exec.dynamic.partition;
    set hive.exec.dynamic.partition.mode;
    在這裏插入圖片描述
    2)打開開關
    語法:set 開關 = 值;
    set hive.exec.dynamic.partition = true;
    set hive.exec.dynamic.partition.mode = nonstrict;
    在這裏插入圖片描述

  3. 編寫動態分區的插入語法
    insert into table student_age partition(age) select id,name,gender,age from student;
    條件:
    ①分區字段必須放在select查詢字段的最後
    ②select查詢字段的名稱要與student_age表字段名稱對應。

    可以看到創建出來的動態分區有7個,每個分區下都有數據。
    在這裏插入圖片描述
    在這裏插入圖片描述
    在這裏插入圖片描述

  4. 查看結果
    select * from student_age where age = 18;
    在這裏插入圖片描述

1.2.2多字段半自動分區

現在我們想根據age和dept字段進行動態分區,dept爲靜態分區,age爲動態分區。

  1. 創建分區表stu_st
    create table stu_st(id int,name string,gender string)
    partitioned by(dept string,age int) # 動態分區字段要放在最後
    row format delimited fields terminated by ‘,’;
  2. 插入數據
    按照dept手動設置進行靜態分區,把age動態劃分進去。
    insert into table stu_st partition(dept=‘IS’,age) select id,name,gender,age from student where dept = ‘IS’;
    同理,把dept分別等於CS和MS的數據也插入進來。
  3. 查看分區
    show partitions stu_st;
    在這裏插入圖片描述
    在HDFS上可以看到根據dept和age字段自動進行分區的數據
    在這裏插入圖片描述
  4. 查看數據
    select * from stu_st where dept = ‘CS’ and age = 19;
    在這裏插入圖片描述

1.2.3多字段全動態分區

現在我們想根據age和dept字段進行全動態分區,dept和age都爲動態分區字段。

  1. 創建分區表stu
    create table stu(id int,name string,gender string)
    partitioned by(dept string,age int)
    row format delimited fields terminated by ‘,’;

  2. 插入數據
    insert into table stu partition(dept,age) select id,name,gender,dept,age from student;

  3. 查看分區
    show partitions stu;
    在這裏插入圖片描述

  4. 查看HDFS上存放的數據信息
    在這裏插入圖片描述
    在這裏插入圖片描述

  5. 查看數據
    select * from stu where dept = ‘CS’ and age = 19;
    在這裏插入圖片描述

全動態分區相關參數調優
  1. 允許創建的最大動態分區個數,默認是100個。
    set hive.exec.max.dynamic.partitions.pernode = 200; # 可設置爲200個
  2. 設爲nonstrict允許所有分區都是動態的,否則必須有靜態分區字段。
    set hive.exec.dynamic.partition.mode = nonstrict; # 默認是strict
  3. 一個動態分區語句最多可以創建多少個動態分區個數,默認是1000個。
    set hive.exec.max.dynamic.partitions = 1000;
  4. 全局最多可以創建多少個文件,默認是100000個。
    set hive.exec.max.created.files = 100000;

小結

  1. 動態分區是按照分區字段的值進行劃分,一個值就是一個分區,每個分區存一個分區字段值的數據。
  2. 如果是多字段動態分區,半自動分區則前n-1個字段必須手動指定分區定義,只有最後一個字段可以進行動態分區。(因爲分區字段必須在select查詢字段的最後,如果你有多個分區字段,只會把最後一個字段當作是分區字段)
  3. 全動態分區則比半自動動態分區更方便,不用自己手動設置靜態分區字段。

2.分桶表

分桶就是按照某種策略拆分成多個文件分別存儲數據。
默認的分桶規則:hash散列

分桶字段的值經過分桶邏輯計算之後得到的餘數相同的都在同一個分桶文件中
一個分桶文件可能存在分桶字段的多個值
一個分桶文件也可能存在沒有任何數據

例子:
分桶的個數:3
AA=0
BB=1
CC=0
DD=1
EE=0
上面的AA和CC和EE都會出現在第一個分桶文件當中
上面的BB和DD都會出現在第二個分桶文件中
第三個分桶文件當中就不會出現任何值。
  1. 創建分桶表
    create table student_bk1(id int,name string,gender string,age int,department string)
    clustered by (id)
    sorted by (age desc)
    into 4 buckets
    row format delimited fields terminated by “,”;

    解釋:
    clustered by (id) :設置分桶字段
    sorted by (age desc) :按照年齡降序,非必須項
    into 4 buckets :設置桶數

    查看student_bk1的元數據信息在這裏插入圖片描述

  2. 打開開關,設置桶數
    set hive.enforce.bucketing = true;
    set mapreduce.job.reduces = 4; # 要跟分桶設置的個數一致

    set mapreduce.job.reduces默認是-1,就是沒有指定

  3. 導入數據
    和分區表一樣,不能直接往分桶表中load數據。
    提示說導入數據需要先導入到一張中間表,再用insert…select導入到分桶表。
    在這裏插入圖片描述
    使用insert…select…
    把student這種中間表通過select查出來,然後放入到sudent_bk1這張分桶表
    insert into table student_bk1 select id,name,gender,age,department from student;

    可以看到導入的數據都是以文件的形式存儲在分桶表的目錄下。
    在這裏插入圖片描述

  4. 查看結果
    hadoop fs -cat hive目錄/分桶文件名

    我們設置了id爲分桶字段,設置了4個桶,這裏的數據劃分是按照id字段值的hash值 % 分桶個數 ,取模來劃分的。不管分桶字段是什麼類型,都返回int整數劃分。

    比如:
    95020%4=0,所以放在0號文件裏
    95013%4=1.所以放在1號文件裏

    因爲我們創建student_bk1的時候,指定了age降序排序,所以數據的插入也是按照age降序排序。
    在這裏插入圖片描述

小結

  1. hash散列是把分桶字段的hash值%分桶個數,餘數相同的劃分同一個桶裏。但是一個桶裏,可能會出現多個不同的字段值。
    比如:
    某個分桶文件存儲了深圳,深圳的hash值%分桶個數,假設其餘數=0,則所有餘數=0(即值爲深圳)會放在一個桶,但是可能廣州的餘數=0,也會放在同一個桶,就會出現深圳、廣州這兩個不同的值在同一個桶。
  2. 如果只想把同一個字段值放在同一個文件下,就必須使用動態分區來做。
    動態分區能保證每個值在一個分區,而且該值的所有記錄,一定都在這個分區。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章