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)多分割槽聯合查詢