1. 程式人生 > >一起學Hive——建立內部表、外部表、分割槽表和分桶表及匯入資料

一起學Hive——建立內部表、外部表、分割槽表和分桶表及匯入資料

Hive本身並不儲存資料,而是將資料儲存在Hadoop的HDFS中,表名對應HDFS中的目錄/檔案。根據資料的不同儲存方式,將Hive表分為外部表、內部表、分割槽表和分桶表四種資料模型。每種資料模型各有優缺點。通過create user命令建立user表時,會在HDFS中生成一個user目錄/檔案。

外部表

資料不由Hive管理,使用drop命令刪除一個表時,只是把表的元資料給刪除了,而表的資料不會刪除。 建立外部表的SQL語句:

create external table bigdata17_user(
userid int,
username string,
fullname string)  
row format delimited fields terminated by ','   
lines terminated by '\n';

在hive的命令列中執行show tables;sql語句,會看到bigdata17_user的表。 hive table

通過執行hadoop fs -ls /user/hive/warehouse/bigdata17.db/bigdata17_user 命令,可以看到在HDFS中有一個bigdata17_user的目錄。這時候資料夾下面是沒有資料的,因為還沒有匯入資料。bigdata17.db是資料庫名,hive預設的資料庫是default。 hive table 執行SQL語句:load data inpath '/data/user.csv' overwrite into table bigdata17_user;匯入資料到bigdata17_user表中。

執行hadoop fs -ls /user/hive/warehouse/bigdata17.db/bigdata17_user命令,就看到該目錄下面有個user.csv的檔案。 hive table 通過drop table bigdata17_user;語句刪除表。 然後執行show tables語句,發現該表已經不存在。

我們再次執行hadoop fs -ls /user/hive/warehouse/bigdata17.db/bigdata17_user,發現bigdata17_user目錄還存在,目錄中還有user.csv檔案。 hive table 通過上述的操作,驗證了使用drop刪除表時是不會刪除外部表的資料。而我們要恢復外部表只需再次執行建立bigdat17_user表的SQL即可:

create external table bigdata17_user(
userid int,
username string,
fullname string)  
row format delimited fields terminated by ','   
lines terminated by '\n';

內部表

內部表(有些人會翻譯成管理表)的資料由hive管理,當使用drop刪除表時,會把表的元資料和資料一起刪除,資料無法恢復,因此一定要慎用drop刪除內部表。

建立內部表的sql語句:

create table bigdata17_user( userid int, username string, fullname string)
row format delimited fields terminated by ','
lines terminated by '\n';

和外部表建立的語法基本一樣,只是建立外部表需要使用external關鍵字。沒有external關鍵字則是建立內部表。

分割槽表

內部表和外部表都可以使用分割槽的功能,使用分割槽的內部或外部表稱為分割槽表。 建立分割槽表的語句:

create external table bigdata17_user_partition(
username string,
fullname string)
partitioned by(userid string)
row format delimited fields terminated by ','   
lines terminated by '\n';

往分割槽表匯入資料分為靜態分割槽匯入和動態分割槽匯入,靜態分割槽是在匯入語句中指定分割槽值,例如:

insert overwrite table bigdata17-user_parttion
 partition(userid=1)
 select username ,fullname from bigdata17_user;

該語句的分割槽值預設是1,如果有多個分割槽值,必須寫多個sql語句,效率低下。

一般情況在我們都是使用動態分割槽匯入資料, 在匯入資料之前必須執行下面的兩條語句讓hive支援動態分割槽功能,預設是不支援動態分割槽的。

set hive.exec.dynamic.partition=true;
set hive.exec.dynamic.partition.mode=nonstrict;

動態分割槽匯入資料的sql語句:

insert overwrite table bigdata17_user_partition
 partition(userid)
 select username ,fullname,userid from bigdata17_user;

我們來看下分割槽表的資料在hdfs中是以何種形式組織存放的,執行hadoop fs -ls /user/hive/warehouse/bigdata17.db/bigdata17_user_partition命令,會看到下圖的內容: hive table 因為bigdata17_user_partition表是按照userid欄位進行分割槽的,bigdata17_user_partition一共有1、2和3的三個數值,因此有3個檔案。由此可見,分割槽欄位有多少個不同的值,就有幾個檔案。相同分割槽的資料存放在同一個檔案中。

注意:在使用insert overwrite table select方式匯入資料到分割槽表時,有多個分割槽欄位時,分割槽partition中的欄位順序必須和select欄位的順序一致。

分桶表

分桶是將某個欄位取雜湊值,值相同的資料分發到一個桶中。在建立分桶表的時候必須指定分桶的欄位,並且指定要分桶的數量。 建立分桶表對SQL語句如下:

create table bigdata17_user_bucket( userid int, username string, fullname string)
clustered by(userid) into 2 buckets  
row format delimited fields terminated by ','
lines terminated by '\n';

匯入資料到bigdata17_user_bucket分桶表中的步驟:

  1. 設定使用分桶屬性:set hive.enforce.bucketing = true。
  2. 執行SQL語句
insert overwrite table bigdata17_user_bucket
 select userid,username ,fullname from bigdata17_user;

執行hadoop fs -ls /user/hive/warehouse/bigdata17.db/bigdata17_user_bucket命令,會看到bigdata17_user_bucket目錄中有兩個檔案。 hive table 其中userid為1和3的資料寫入到000001_0檔案中,userid為2的資料寫入到000000_0的檔案中。

注意:分割槽和分桶都是按欄位來組織資料的存放,分割槽是相同的欄位值存放在一個檔案中,而分桶是欄位雜湊值相同的資料存放在一個檔案中。