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