hive ddl语法使用详解
一、前言
DDL,也叫數據定義語言 (Data Definition Language, DDL),是SQL語言集中對數據庫內部的對象結構進行創建,刪除,修改等的操作語言,這些數據庫對象包括database、table等,使用過mysql的同學應該對此很了解了;
hive中ddl核心操作
- 核心語法由CREATE、ALTER與DROP三個所組成;
- DDL不涉及表內部數據的操作;
二、Hive中DDL語法特點
Hive SQL(HQL)與標準SQL的語法大同小異,基本相通,使用過標準sql的同學上手hive sql時基本無壓力,但hive的復雜查詢語法相對標準sql來說,細節上又略有不同,后續在實操中可以發現;
HQL中create語法(尤其create table)將是學習掌握Hive DDL語法的重中之重,建表是否成功直接影響數據文件是否映射成功,進而影響后續是否可以基于SQL分析數據
三、Hive中的database
數據庫是數據表的基本承載體,現有數據庫才會有表,Hive中的數據庫有下面的特點
1、默認數據庫為default
存儲數據位置位于HDFS的/user/hive/warehouse下;
比如我們創建了一個test的數據庫,從hdfs的web界面上就能清楚的看到存儲位置;
2、用戶可自定義數據庫
用戶自己創建的數據庫存儲位置是/user/hive/warehouse/database_name.db下
3、創建數據庫
hive中創建數據庫基本語法如下:
CREATE (DATABASE|SCHEMA) [IF NOT EXISTS] database_name [COMMENT database_comment] [LOCATION hdfs_path] [WITH DBPROPERTIES (property_name=property_value, ...)];參數說明:
- COMMENT:數據庫的注釋說明語句;
- LOCATION:指定數據庫在HDFS存儲位置,默認/user/hive/warehouse/dbname.db;
- WITH DBPROPERTIES:用于指定一些數據庫的屬性配置;
避免要創建的數據庫已經存在錯誤,增加?if?not?exists?判斷,這是一個好的習慣;
創建一個數據庫
create database if not exists hero comment "this is my first db" with dbproperties ('createdBy'='congge');?
注意:如果需要使用location指定路徑的時候,最好指向的是一個新創建的空文件夾
切換數據庫(使用新的數據庫)
use databaseName刪除數據庫
完整語法
DROP ( DATABASE | SCHEMA ) [ IF EXISTS ] database_name [ RESTRICT | CASCADE ];關于刪除數據庫的幾點說明:
- 默認行為是RESTRICT,這意味著僅在數據庫為空時才刪除它;
- 要刪除帶有表的數據庫(不為空的數據庫),我們可以使用CASCADE;
查看數據庫詳情
desc database databaseName;
顯示數據庫詳細信息
使用extended
desc database extended test;?
修改數據庫
用戶可以使用 ALTER DATABASE 命令為某個數據庫的 DBPROPERTIES 設置鍵-值對屬性值, 來描述這個數據庫的屬性信息。
三、Hive中的table
數據表是hive用來做數據分析的基本模型,因此有必要深入掌握hive的創建表語法相關的知識;
建表基本語法
CREATE TABLE [IF NOT EXISTS] [db_name.]table_name (col_name data_type [COMMENT col_comment], ... ) [COMMENT table_comment] [ROW FORMAT DELIMITED …];完整的建表語法樹
//HIVE DDL CREATE TABLEcreate[temporary][external]table[if not exists][db_name.]table_name[(col_name data_type[comment col_conmment],...)][comment table_comment][partitioned by(col_name col_type[comment col_comment],...)][clustered by(col_name col_type,...)[sorted by (col_name[ASC|DESC],...)]into num_buckets buckets][row format delimited|serde serde_name with serdeproperties (property_name=property_value,...)][stored as file_foramt][location hdfs_path][tblproperties(property_name=property_value,...)];關于語法樹中的關鍵參數說明
1、CREATE TABLE 創建一個指定名字的表,如果庫中已有相同名的表,則拋出異常;用戶可以使用 IF NOT EXISTS 選項來忽略此異常;
2、EXTERNAL 關鍵字可以讓用戶創建一個外部表(默認創建內部表)。外部表在建表的同時必須指定一個指向實際數據的路徑(LOCATION),Hive在創建內部表時,會將數據移動到數據倉庫指向的路徑;若創建外部表,僅記錄數據所在的路徑,不對數據的位置做任何改變。在刪除表的時候,內部表的元數據和數據會被一起刪除,而外部表只刪除元數據,不刪除數據。
3、COMMENT 是給表字段或者表內容添加注釋說明的;
4、PARTITIONED BY 給表做分區,決定了表是否為分區表;
5、CLUSTERED BY 對于每一個表(table)或者分區, Hive 可以進一步組織成桶,也就是說桶是更為細粒度的數據范圍劃分,Hive采用對列值哈希,然后除以桶的個數求余的方式決定該條記錄存放在哪個桶當中;
6、ROW FORMAT DELIMITED FIELDS TERMINATED BY ‘,’, 這里指定表存儲中列的分隔符,默認是 \001,這里指定的是逗號分隔符,還可以指定其他列的分隔符;
7、STORED AS SEQUENCEFILE|TEXTFILE|RCFILE,如果文件數據是純文本,可以使用 STORED AS TEXTFILE,如果數據需要壓縮,使用 STORED AS SEQUENCEFILE;
8、LOCATION 定義 hive 表的數據在 hdfs 上的存儲路徑,一般管理表(內部表不不要自定義),但是如果定義的是外部表,則需要直接指定一個路徑;
注意事項補充說明
- 語法中的關鍵參數(關鍵字),用于指定某些功能;
- [ ]中括號的語法表示可選;
- 建表語句中的語法順序要和語法樹中順序保持一致;
- 最低限度必須包括的語法如下
CREATETABLE[IF NOT EXISTS] [db_name.]table_name (col_name data_type [COMMENT col_comment], ... )
[COMMENT table_comment]
[ROW FORMAT DELIMITED …];
ROW FORMAT 說明
ROW FORMAT這一行所代表的是跟讀寫文件、序列化SerDe相關的語法,功能有二:
- 使用哪個SerDe類進行序列化;
- 如何指定分隔符;
ROW FORMAT可以說是建表語句中非常重要的一個語法,尤其是分隔符的指定是否合適對后續的數據分析將會帶來重要的影響,而SerDe說的是與hive文件讀寫機制相關的,顧名思義就是序列化與反序列化;
hive文件讀寫機制說明
hive文件讀流程
首先調用InputFormat(默認TextInputFormat),返回一條一條的kv鍵值對記錄(默認是一行對應一條鍵值對)。然后調用SerDe(默認LazySimpleSerDe)的Deserializer,將一條記錄中的value根據分隔符切分為各個字段
Hive寫文件機制
將Row寫入文件時,首先調用SerDe(默認LazySimpleSerDe)的Serializer將對象轉換成字節序列,然后調用OutputFormat將數據寫入HDFS文件中
SerDe相關語法
- 其中ROW FORMAT是語法關鍵字,DELIMITED和SERDE二選其一;
- 如果使用delimited表示使用默認的LazySimpleSerDe類來處理數據;
- 如果數據文件格式比較特殊可以使用ROW FORMAT SERDE serde_name指定其他的Serde類來處理數據,甚至支持用戶自定義SerDe類;
LazySimpleSerDe 分隔符指定
LazySimpleSerDe是Hive默認的序列化類,包含4種子語法,分別用于指定字段之間、集合元素之間、map映射 kv之間、換行的分隔符號,在建表的時候可以根據數據的特點靈活搭配使用;
?Hive默認分隔符
Hive建表時如果沒有row format語法指定分隔符,則采用默認分隔符;
默認的分割符是'\001',是一種特殊的字符,使用的是ASCII編碼的值,鍵盤是打不出來的
Hive數據存儲路徑說明
在上面的建表語句中,注意到最后有一個LOCATION的關鍵字,這就是用于指定數據表的存放路徑的;
hive默認數據存儲路徑
我們知道,hive本身并不存儲數據,數據存放在hdfs上面,所以默認情況下,Hive表默認存儲路徑是由${HIVE_HOME}/conf/hive-site.xml配置文件的hive.metastore.warehouse.dir屬性指定,默認值是:/user/hive/warehouse;
在該路徑下,文件將根據所屬的庫、表,有規律的存儲在對應的文件夾下
如下在上面創建了一個test的數據庫,hdfs上面的位置如下:
指定存儲路徑
Hive建表時,也可以通過location語法來更改數據在HDFS上的存儲路徑,使得建表加載數據更加靈活方便,在這種情況下,對于已經生成好的數據文件,直接使用location指定路徑將會很方便的將數據加載到hive的數據表中;
語法:LOCATION '<hdfs_location>'
四、Hive中的數據類型
Hive數據類型指的是表中列的字段類型,整體分為兩類:
- 原生數據類型(primitive data type);
- 復雜數據類型(complex data type);
最常用的數據類型是字符串String和數字類型Int
原生數據類型
數值類型,時間日期類型,字符串類型,雜項數據類型;
復雜數據類型
array數組、map映射、struct結構、union聯合體
?hive中的數據類型補充說明
- 數據類型英文字母大小寫不敏感;
- 除SQL數據類型外,還支持Java數據類型,比如字符串string;
- 復雜數據類型的使用通常需要和分隔符指定語法配合使用;
- 如果定義的數據類型和文件不一致,Hive會嘗試隱式轉換,但是不保證成功;
hive中數據類型的隱式轉換
我們知道對某些類型的數據庫來說,如果插入的數據類型與定義的類型不一致將無法成功寫入數據,但hive中,在某些情況下對特定的數據類型存在隱式轉換,其特點如下:
- 與標準SQL類似,HQL支持隱式和顯式類型轉換;
- 原生類型從窄類型到寬類型的轉換稱為隱式轉換,反之,則不允許;
下表描述了類型之間允許的隱式轉換:
hive中數據類型的隱式轉換
顯式類型轉換使用CAST函數,例如,CAST('100'as INT)會將100字符串轉換為100整數值,如果強制轉換失敗,例如CAST(‘Allen'as INT),該函數返回NULL
五、Hive建表實操
建表練習之 —— 簡單數據類型的操作
數據準備
如下為即將導入數據目錄的原始數據文件(游戲中的英雄人物),其中字段之間分隔符為制表符\t,要求在Hive中建表映射成功該文件,字段文件的含義分別是:id、name(英雄名稱)、hp_max(最大生命)、mp_max(最大法力)、attack_max(最高物攻)、defense_max(最大物防)、attack_range(攻擊范圍)、role_main(主要定位)、role_assist(次要定位);
分析:
- 字段都是基本類型,字段的順序需注意;
- 字段之間的分隔符是制表符,需要使用row format語法進行指定;
數據建表語句
drop table t_hero; --ddl create table create table t_hero(id int comment "ID",name string comment "英雄名稱",hp_max int comment "最大生命",mp_max int comment "最大法力",attack_max int comment "最高物攻",defense_max int comment "最大物防",attack_range string comment "攻擊范圍",role_main string comment "主要定位",role_assist string comment "次要定位" ) comment "王者榮耀英雄信息" row format delimited fields terminated by "\t";運行上面的sql建表語句
hdfs上面可以看到已成功創建了?
?
上傳數據文件到hdfs的表目錄下
使用下面的命令進行文件上傳
hdfs dfs -put ./hero.txt /user/hive/warehouse/test.db/t_hero
上傳完畢后,在hdfs目錄下可以看到上面的這個文件,查看hero表,檢查數據是否映射到表中
通過這種方式就完成了一個hive建表之后,通過映射文件的方式將數據導到hive表的過程,也是日常開發運維中比較常用的一種方式;
建表練習之 —— 復雜類型數據操作
數據準備
在當前目錄下,創建一個數據文件,內容如下,文件中的內容記錄了某手游熱門英雄的相關皮膚價格信息;
分析這段內容,可以從得出下面幾點:
- 字段:id、name(英雄名稱)、win_rate(勝率)、skin_price(皮膚及價格);
- 前3個字段原生數據類型、最后一個字段復雜類型map;
- 需要指定字段之間分隔符、集合元素之間分隔符、map kv之間分隔符;
建表sql
create table t_hot_hero_skin_price(id int,name string,win_rate int,skin_price map<string,int> ) row format delimited fields terminated by ',' collection items terminated by '-' map keys terminated by ':'; -- 集合元素之間的分隔符執行sql創建表
上傳數據文件到數據表目錄進行數據映射
執行下面命令進行hdfs文件上傳
hdfs dfs -put ./hot_hero_skin_price.txt /user/hive/warehouse/test.db/t_hot_hero_skin_price
上傳成功后再次查看數據表,就能看到映射的數據了;
建表練習之 ——?默認分隔符使用
還記得在上文中提到的,hive中的默認分隔符嗎?hive中默認的分割符是'\001',是一種特殊的字符,使用的是ASCII編碼的值,鍵盤是打不出來的;
數據準備
有如下數據文件,每行數據不同字段之間以默認分隔符分開;
分析這段內容,得出下面幾點
- 字段:id、team_name(戰隊名稱)、ace_player_name(選手名字);
- 數據都是原生數據類型,且字段之間分隔符是\001,因此在建表的時候可以省去row format語句,因為hive默認的分隔符就是\001;
建表sql
由于是默認分隔符,就可以省去row_format;
create table t_team_ace_player(id int,team_name string,ace_player_name string );執行sql創建表
上傳數據文件到hdfs的表目錄下
使用下面的命令進行文件上傳
hdfs dfs -put ./team_ace_player.txt /user/hive/warehouse/test.db/t_team_ace_player
上傳完畢后,在hdfs目錄下可以看到上面的這個文件,查看hero表,檢查數據是否映射到表中
建表練習之 ——?指定數據存儲路徑
在上面的建表練習中,我們并沒有在建表語句中指定LOCATION的信息,而是最后通過將數據文件上傳到數據表的hdfs文件目錄下映射的,其實在某些情況下,這種方式操作起來看起來有點麻煩,于是就可以通過指定LOCATION的方式,就能完成任意目錄下的文件映射到hive中的目的;
hsfs創建數據目錄
在hdfs的根目錄下,創建一個名叫data的目錄
hdfs dfs -mkdir /data
上傳數據文件到自建目錄下
仍然使用上面的那個數據文件進行上傳;
hdfs dfs -put ./team_ace_player.txt /data
建表sql(注意指定LOCATION)
create table t_team_ace_player_location(id int,team_name string,ace_player_name string)location '/data';執行sql的創建;?
?執行完成之后查看一下表的數據,可以發現已經映射成功了;
總結
以上是生活随笔為你收集整理的hive ddl语法使用详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 查找相交链表相交节点
- 下一篇: css样式border-radius学习