1. 程式人生 > >HiveQL的DDL操作(一)——建立、查詢、修改、刪除表

HiveQL的DDL操作(一)——建立、查詢、修改、刪除表

DDL(data definition language)資料庫定義語言:

關鍵詞:create、alter、drop,對庫和表的操作。

一、建立表

1.1 建立表的完整語法及欄位解釋

create (external) table (if not exists) table_name (
col_name data_type , ...)

comment table_comment
partitioned by (col_name data_type)
clustered by (col_name , col_name , ...)
sorted by (col_name [ASC|DESC], ...)] into num_buckets BUCKETS

row format delimited fields terminated by '\t'

stored as file_format
location hdfs_path
tblproperties (property_name = property_value , ...)

as select_statement
like table table_name

(1)external關鍵詞:建立外部表;

ps:刪除表的時候,外部表只刪除儲存在meta store中的元資料,儲存在HDFS中的資料不會刪除,外部表適合共享資料資訊;

                                 內部表會把元資料和資料一起刪除。

(2)col_name data_type:欄位名 欄位資料型別;

(3)comment:為表和列添加註釋;

(4)partitioned by:建立分割槽表;

(5)clustered by:建立分桶表;

(6)sorted by:對一個桶中的一個或多個列進行排序;

(7)row format delimited fields terminated by '\t':表中行的格式是通過製表符'\t'進行分隔的;

(8)stored as:指定儲存檔案的型別,

         常用的有三種textfile(文字)、sequencefile(二進位制序列檔案,資料可以壓縮)、rcfile(列式儲存格式檔案);

(9)location:指定表在HDFS中的儲存路徑(資料夾);

(10)tblproperties:為表增加屬性資訊;

(11)as:後跟查詢語句,表示根據查詢結果來建立表;

(12)like:複製現有表的結果,但是不復制資料。

 

1.2 管理表(內部表)

預設建立的表都是管理表,有時也稱內部表。刪除管理表時,Hive會刪除meta store中的元資料和儲存在HDFS中的資料,所以管理表不適合共享資料。

(1)普通建立表

create table if not exists table1(id int, name string)
row format delimited fields terminated by '\t'
stored as textfile
location '/user/hive/warehouse/table1';

建立表在指定路徑table1這個資料夾下,在當前資料庫中儲存;

ps:如果沒有location指定表的儲存路徑,它會預設儲存在當前資料庫路徑的資料夾下,在當前資料庫中儲存。

create table if not exists table2(id int, name string)
row format delimited fields terminated by '\t'
stored as textfile;

(2)根據查詢結果建立表(create table ~ as select * from ~)

hive (hive_db1)> create table table3 as select * from table1;

(3)根據已存在的表結構建立表(create table ~ like ~)

hive (hive_db1)> create table table4 like table1;

(4)查詢表的型別(desc formatted ~)

hive (hive_db1)> desc formatted table1;

ps:對比查詢詳細資料庫資訊:desc database extended ~

 

1.3 外部表

前面有說過外部表適用於在HDFS中共享資料的表,因為刪除外部表,只會刪除meta store中的元資料,不刪除HDFS中的資料。

案例:建立table5外部表,並向其中匯入資料

(1)先上傳資料到HDFS中

hive (hive_db1)> dfs -mkdir /student;
hive (hive_db1)> dfs -put /opt/module/datas/student.txt /student;

檢視一下檔案student.txt中的資訊

[[email protected] datas]$ cat student.txt 
1002	lisi
1003	wangwu
1004	zhaoliu

(2)建立外部表

hive (hive_db1)> create external table table_external(id int , name string)
               > row format delimited fields terminated by '\t'
               > location '/student';

(3)檢視建立外部表的資料

hive (hive_db1)> select * from table_external;
OK
table_external.id	table_external.name
1002	lisi
1003	wangwu
1004	zhaoliu

ps:這就是外部表和內部表的區別,內部表是先建立,再匯入資料;

       外部表多是在HDFS上已有資料檔案,在相同資料夾中建立外部表,查詢外部表適,外部表能通過相同的欄位名,自動匹配對應的當前資料夾下的檔案資料顯示出來。

問題:外部表的查詢資料匹配原理

既然外部表查詢顯示的是相同資料夾下的資料檔案的資訊,那外部表是如何匹配資料檔案的呢?如果相同目錄下有兩個檔案,查詢外部表會匹配哪個資料檔案呢?

往/student目錄下再匯入資料檔案student2、student3,三個資料檔案資訊如下

我們再建立一個欄位都是string型別的外部表table_external2

hive (hive_db1)> create external table table_external2(sort string , name string)
               > row format delimited fields terminated by '\t'
               > location '/student';

查詢外部表1

hive (hive_db1)> select * from table_external;
OK
table_external.id	table_external.name
1002	lisi
1003	wangwu
1004	zhaoliu
NULL	lisi
NULL	wangwu
NULL	zhaoliu
NULL	lisi    1
NULL	wangwu  2
NULL	zhaoliu 3

查詢外部表2

table_external2.sort	table_external2.name
1002	lisi
1003	wangwu
1004	zhaoliu
yi	lisi
er	wangwu
san	zhaoliu
yi	lisi    1
er	wangwu  2
san	zhaoliu 3

結論:在同一個資料夾下存在多個資訊檔案時,查詢該資料夾下任意一個外部表,都會顯示所有檔案的全部資訊,資訊與外部表字段型別不匹配的,會顯示null。

(4)刪除外部表

hive (hive_db1)> drop table table_external;

刪除外部表後,發現HDFS上的資料檔案並未消失,但metadata中外部表的元資料已刪除。

這就是外部表的原理,建立外部表後不需要匯入資訊,查詢時,顯示的是HDFS中已有的資料資訊。

 

1.4 管理表與外部表的相互轉換

(1)查詢表的型別

hive (hive_db1)> desc formatted table1;

(2)內部表 ->外部表(EXTERNAL和TRUE必須為大寫)

hive (hive_db1)> alter table table1 set tblproperties('EXTERNAL'='TRUE');

(3)外部表 ->內部表(EXTERNAL和FALSE必須為大寫)

hive (hive_db1)> alter table table1 set tblproperties('EXTERNAL'='FALSE');

 

二、分割槽表

Hive中的分割槽其實就是分目錄,一個分割槽表對應HDFS檔案系統上一個獨立的資料夾,該資料夾下是該分割槽所有的資料檔案;

查詢時,通過where表示式選擇查詢所指定的分割槽即可,不用再查詢整張表的所有資料,提高海量資料查詢的效率。

(1)建立分割槽表

hive (hive_db1)> create table stu_par(id int , name string)
               > partitioned by (month string)
               > row format delimited fields terminated by '\t';

表的欄位 id,name;分割槽欄位為month

注意:建立分割槽表時,分割槽欄位不能是表中的已有欄位,否則會報錯column repeated in partitioning columns;這也說明分割槽欄位並不是表中的一列,它是一個偽列,對應HDFS中的一個分割槽資料夾。

(2)往分割槽表裡導資料(load data local inpath '~' into table ~ partition(分割槽欄位 = '~'))

hive (hive_db1)> load data local inpath '/opt/module/datas/student.txt' into table stu_par partition(month = '12');

相同的方法,給分割槽month=11和month=10也匯入student.txt的資料;

ps:由於建立分割槽表時,沒有指定location,它預設儲存在當前資料庫/hive路徑下,建立分割槽後:

看到在/hive_db1/stu_par目錄下,有三個month資料夾;

/hive_db1是當前資料庫的預設路徑,stu_par是分割槽表的儲存路徑,三個month是三個分割槽的儲存路徑,每個month資料夾下都有一個student.txt檔案;

這就是分割槽表在HDFS上的儲存詳情。

ps:如果在default資料庫中建立分割槽表,它的預設儲存位置是/user/hive/warehouse/stu_par

(3)查詢分割槽表的單個分割槽欄位(select * from ~ where 分割槽欄位 = '~')

為了方便顯示,接下來用JDBC客戶端連線hive,查詢如下:

0: jdbc:hive2://hadoop100:10000> select * from stu_par where month='12';
+-------------+---------------+----------------+--+
| stu_par.id  | stu_par.name  | stu_par.month  |
+-------------+---------------+----------------+--+
| 1002        | lisi          | 12             |
| 1003        | wangwu        | 12             |
| 1004        | zhaoliu       | 12             |
+-------------+---------------+----------------+--+

(4)多分割槽聯合查詢