工作時,數據統計分析、挖掘的時候用到很多Hive方面的內容,就做了一個完整的整理文檔。
· hive是基於Hadoop的一個數據倉庫工具,可以將結構化的數據文件映射爲一張數據庫表,並提供簡單的sql查詢功能,可以將sql語句轉換爲MapReduce任務進行運行。其優點是學習成本低,可以通過類SQL語句快速實現簡單的MapReduce統計,不必開發專門的MapReduce應用,十分適合數據倉庫的統計分析。
· Hive 定義了簡單的類 SQL查詢語言,稱爲 HQL,它允許熟悉 SQL的用戶查詢數據。
· Hive 將用戶的HiveQL語句通過解釋器轉換爲MapReduce作業提交到Hadoop集羣上,Hadoop 監控作業執行過程,然後返回作業執行結果給用戶。Hive並非爲聯機事務處理而設計,Hive並不提供實時的查詢和基於行級的數據更新操作。Hive的最佳使用場合是大數據集的批處理作業,例如,網絡日誌分析。
Tip1: Hadoop
是一個開源框架來存儲和處理大型數據在分佈式環境中。它包含兩個模塊,一個是MapReduce,另外一個是Hadoop分佈式文件系統(HDFS)。
•MapReduce:一種並行編程模型在大型集羣普通硬件可用於處理大型結構化,半結構化和非結構化數據。
•HDFS:Hadoop分佈式文件系統是Hadoop的框架的一部分,用於存儲和處理數據集。它提供了一個容錯文件系統在普通硬件上運行。
Hadoop生態系統包含了用於協助Hadoop的不同的子項目(工具)模塊,如Sqoop, Pig和 Hive。
•Sqoop: 它是用來在HDFS和RDBMS之間來回導入和導出數據。
•Pig: 它是用於開發MapReduce操作的腳本程序語言的平臺。
•Hive: 它是用來開發SQL類型腳本用於做MapReduce操作的平臺。
注:有多種方法來執行MapReduce作業:
•傳統的方法是使用Java MapReduce程序結構化,半結構化和非結構化數據。
•針對MapReduce的腳本的方式,使用Pig來處理結構化和半結構化數據。
•Hive查詢語言(HiveQL或HQL)採用Hive爲MapReduce的處理結構化數據。
1.1Hive 體系結構
1、用戶接口
用戶接口主要有三個:CLI,Client和 WUI。其中最常用的是 CLI,Cli啓動的時候,會同時啓動一個 Hive副本。Client 是 Hive 的客戶端,用戶連接至 Hive Server。在啓動 Client模式的時候,需要指出 Hive Server所在節點,並且在該節點啓動 Hive Server。 WUI是通過瀏覽器訪問Hive。
2、元數據存儲
Hive 將元數據存儲在數據庫中,如 mysql、derby。Hive中的元數據包括表的名字,表的列和分區及其屬性,表的屬性(是否爲外部表等),表的數據所在目錄等。
3、解釋器、編譯器、優化器、執行器
解釋器、編譯器、優化器完成 HQL查詢語句從詞法分析、語法分析、編譯、優化以及查詢計劃的生成。生成的查詢計劃存儲在 HDFS中,並在隨後由 MapReduce調用執行。
4、Hadoop
Hive 的數據存儲在 HDFS中,大部分的查詢由 MapReduce完成。
1.2 Hive數據存儲
首先Hive沒有專門的數據存儲格式,也沒有爲數據建立索引,用戶可以非常自由的組織 Hive中的表,只需要在創建表的時候告訴 Hive數據中的列分隔符和行分隔符,Hive就可以解析數據。
其次,Hive中所有的數據都存儲在 HDFS 中,Hive中包含以下數據模型:表(Table),外部表(External Table),分區(Partition),桶(Bucket)。
Hive 中的 Table和數據庫中的 Table在概念上是類似的,每一個 Table在 Hive 中都有一個相應的目錄存儲數據。例如,一個表 pvs,它在 HDFS中的路徑爲:/wh/pvs,其中,wh是在 hive-site.xml中由 ${hive.metastore.warehouse.dir}指定的數據倉庫的目錄,所有的 Table數據(不包括 External Table)都保存在這個目錄中。
Partition 對應於數據庫中的 Partition列的密集索引,但是 Hive中 Partition的組織方式和數據庫中的很不相同。在 Hive中,表中的一個 Partition對應於表下的一個目錄,所有的 Partition的數據都存儲在對應的目錄中。例如:pvs表中包含 ds 和 city 兩個 Partition,則對應於 ds = 20090801, ctry = US的 HDFS 子目錄爲:/wh/pvs/ds=20090801/ctry=US;對應於 ds = 20090801, ctry = CA的 HDFS 子目錄爲;/wh/pvs/ds=20090801/ctry=CA
Buckets 對指定列計算 hash,根據 hash值切分數據,目的是爲了並行,每一個 Bucket對應一個文件。將 user列分散至 32 個 bucket,首先對 user列的值計算 hash,對應 hash值爲 0 的 HDFS 目錄爲:/wh/pvs/ds=20090801/ctry=US/part-00000;hash值爲 20 的 HDFS 目錄爲:/wh/pvs/ds=20090801/ctry=US/part-00020
External Table 指向已經在 HDFS 中存在的數據,可以創建 Partition。它和 Table在元數據的組織上是相同的,而實際數據的存儲則有較大的差異。
Table 的創建過程和數據加載過程(這兩個過程可以在同一個語句中完成),在加載數據的過程中,實際數據會被移動到數據倉庫目錄中;之後對數據對訪問將會直接在數據倉庫目錄中完成。刪除表時,表中的數據和元數據將會被同時刪除。
1.3Hive創建數據庫
CREATE DATABASE語句
創建數據庫是用來創建數據庫在Hive中語句。在Hive數據庫是一個命名空間或表的集合。此語法聲明如下:
CREATEDATABASE|SCHEMA[IF NOT EXISTS]<database name>
IF NOT EXISTS是一個可選子句,通知用戶已經存在相同名稱的數據庫。
可以使用SCHEMA在DATABASE的這個命令。下面的查詢執行創建一個名爲userdb數據庫:
hive> CREATE DATABASE[IF NOT EXISTS] userdb;
或,hive> CREATE SCHEMA userdb;
以下的查詢用於驗證數據庫列表:
hive>SHOW DATABASES;
default
userdb
JDBC 程序
在JDBC程序(HiveCreateDb.java文件)來創建數據庫如下。
import java.sql.SQLException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.DriverManager;
publicclassHiveCreateDb{
privatestaticStringdriverName="org.apache.hadoop.hive.jdbc.HiveDriver";
publicstaticvoid main(String[] args)throwsSQLException{
// Register driver and createdriver instance
Class.forName(driverName);
// get connection
Connection con=DriverManager.getConnection("jdbc:hive://localhost:10000/default","","");
Statement stmt= con.createStatement();
stmt.executeQuery("CREATEDATABASE userdb");
System.out.println(“Database userdbcreated successfully.”);
con.close();
}
}
JDBC :數據庫連接,一個JAVA API可訪問任何類型表列數據,用於連接到數據庫;創建SQL或MySQL語句;在數據庫中執行SQL或MySQL查詢;查看和修改數據庫中的數據記錄。
1.4Hive刪除數據庫
DROP DATABASE語句
DROP DATABASE是刪除所有的表並刪除數據庫的語句。它的語法如下:
DROP DATABASEStatementDROP (DATABASE|SCHEMA) [IF EXISTS] database_name
[RESTRICT|CASCADE];
刪除名稱爲userb的數據庫;
hive> DROP DATABASE IF EXISTS userdb;
使用CASCADE查詢刪除數據庫。這意味着要全部刪除相應的表在刪除數據庫之前;
hive> DROP DATABASE IF EXISTS userdb CASCADE;
使用SCHEMA查詢刪除數據庫;
hive> DROP SCHEMA userdb;
另外也可通過JDBC程序刪除數據庫。
1.5 Hive創建表
Create Table是用於在Hive中創建表的語句。語法和示例如下:
語法:
CREATE [TEMPORARY][EXTERNAL] TABLE [IF NOTEXISTS][db_name.] table_name
[(col_namedata_type[COMMENT col_comment],...)]
[COMMENTtable_comment]
[ROWFORMAT row_format]
[STOREDAS file_format]
示例:需使用CREATE TABLE語句創建一個名爲employee表。employee表中的字段和數據類型如下:
Sr.No |
字段名稱 |
數據類型 |
1 |
Eid |
int |
2 |
Name |
String |
3 |
Salary |
Float |
4 |
Designation |
string |
下面的數據是一個註釋,行格式字段,如字段終止符,行終止符,並保存的文件類型。
COMMENT ‘Employee details’
FIELDSTERMINATED BY ‘\t’
LINES TERMINATEDBY ‘\n’
STORED IN TEXTFILE
下面的查詢創建使用上述數據的表名爲 employee。
hive>CREATE TABLE IF NOT EXISTS employee( eidint,nameString,
>salaryString, destinationString)
> COMMENT‘Employee details’
> ROWFORMAT DELIMITED
> FIELDSTERMINATED BY‘\t’
> LINESTERMINATED BY‘\n’
> STOREDAS TEXTFILE;
如果添加選項IF NOT EXISTS,Hive忽略大小寫,萬一表已經存在的聲明。
成功創建表後,能看到以下回應:
OK
Time taken:5.905 seconds
hive>
LOAD DATA語句
一般來說,在SQL創建表後,可以使用INSERT語句插入數據。但在Hive中,可使用LOAD DATA語句插入數據。
同時將數據插入到Hive,最好是使用LOAD DATA來存儲大量記錄。有兩種方法用來加載數據:一種是從本地文件系統,另一種是從Hadoop文件系統。
加載數據:
LOAD DATA [LOCAL] INPATH'filepath'[OVERWRITE] INTOTABLE tablename
[PARTITION(partcol1=val1,partcol2=val2...)]
• LOCAL是標識符指定本地路徑。它是可選的。
• OVERWRITE是可選的,覆蓋表中的數據。
• PARTITION這是可選的
例如;插入在/home/user目錄中名爲sample.txt文件的數據。
hive> LOADDATA LOCAL INPATH'/home/user/sample.txt'
> OVERWRITE INTO TABLE employee;
1.6 Hive 修改表
修改表的屬性,如,修改表名,修改列名,添加列,刪除或替換列。
Alter Table 語句
語法:聲明接受任意屬性,我們希望在一個表中修改以下語法。
ALTER TABLE name RENAME TOnew_name
ALTER TABLE name ADDCOLUMNS (col_spec[, col_spec...])
ALTER TABLE name DROP [COLUMN]column_name
ALTER TABLE name CHANGEcolumn_name new_name new_type
ALTER TABLE name REPLACECOLUMNS(col_spec[, col_spec...])
Rename To… 查詢重命名錶,把 employee修改爲 emp
hive> ALTER TABLE employee RENAME TO emp;
Change …修改列名和列數據類型:
下表爲例,顯示employee表中字段要被更改(粗體)。
字段名 |
從數據類型轉換 |
更改字段名稱 |
轉換爲數據類型 |
eid |
int |
eid |
int |
name |
String |
ename |
String |
salary |
Float |
salary |
Double |
designation |
String |
designation |
String |
語句;
hive>ALTER TABLE employee CHANGE name enameString;
hive> ALTER TABLE employeeCHANGE salary salaryDouble;
添加列語句
下面的查詢增加了一個列名dept在employee表。
hive>ALTER TABLE employee ADD COLUMNS(
> dept STRING COMMENT'Department name');
REPLACE語句
以下從employee表中查詢使用empid代替eid列,name代替ename列
hive>ALTER TABLE employee REPLACE COLUMNS(
>eid INT empidInt,
> ename STRING nameString);
1.7Hive刪除表
Drop Table語句
語法:
DROP TABLE[IFEXISTS] table_name;
以下查詢刪除一個名爲 employee的表:
hive> DROP TABLE IF EXISTSemployee;
查詢驗證表的列表
hive>SHOW TABLES;
emp
ok
Time taken:2.1 seconds
1.8Hive分區
分區含義;組織表到分區。它是將一個表到基於分區列,如日期,城市和部門的值相關方式。使用分區,很容易對數據進行部分查詢。
表或分區是細分成桶,以提供額外的結構,可以使用更高效的查詢的數據。桶的工作是基於表的一些列的散列函數值。
例如,一個Tab1表包含僱員數據,如 id, name, dept和yoj (即加盟年份),如果用年份分區僱員數據並將其存儲在一個單獨的文件,它減少了查詢處理時間。下例表示分區的文件和數據;
employee 數據表中,
/tab1/employeedata/file1
id, name, dept, yoj
1, gopal, TP, 2012
2, kiran, HR, 2012
3, kaleel,SC, 2013
4, Prasanth, SC, 2013
上面的數據被劃分成使用年兩個文件。
/tab1/employeedata/2012/file2
1, gopal, TP, 2012
2, kiran, HR, 2012
/tab1/employeedata/2013/file3
3, kaleel,SC, 2013
4, Prasanth, SC,2013
添加分區
可以通過添加分區表改變所述表。假設我們有一個表叫employee,擁有如 Id, Name, Salary,Designation, Dept,和 yoj等字段。
語法:
ALTER TABLE table_name ADD[IF NOT EXISTS] PARTITION partition_spec
[LOCATION'location1'] partition_spec[LOCATION'location2']...;
partition_spec:
:(p_column= p_col_value, p_column= p_col_value,...)
以下查詢用於將分區添加到employee表。
hive>ALTER TABLE employee
>ADD PARTITION(year=’2013’)
> location'/2013/part2013';
重命名分區
此命令的語法如下。
ALTER TABLE table_namePARTITION partition_spec RENAME TO PARTITION partition_spec;
hive>ALTER TABLE employee PARTITION(year=’1203’)
> RENAME TO PARTITION(Yoj=’1203’);
刪除分區
下面語法用於刪除分區:
ALTER TABLE table_name DROP[IF EXISTS] PARTITION partition_spec, PARTITIONpartition_spec,...;
以下查詢是用來刪除分區:
hive>ALTER TABLE employee DROP[IF EXISTS]
>PARTITION(year=’1203’);
1.9Hive內置運算符
在Hive有四種類型的運算符:
• 關係運算符
• 算術運算符
• 邏輯運算符
• 複雜運算符
關係運算符;用來比較兩個操作數
下表描述Hive中可用的關係運算符:
運算符 |
操作 |
描述 |
A = B |
所有基本類型 |
如果表達A等於表達B,結果TRUE,否則FALSE。 |
A != B |
所有基本類型 |
如果A不等於表達式B表達返回TRUE,否則FALSE。 |
A < B |
所有基本類型 |
TRUE,如果表達式A小於表達式B,否則FALSE。 |
A <= B |
所有基本類型 |
TRUE,如果表達式A小於或等於表達式B,否則FALSE。 |
A > B |
所有基本類型 |
TRUE,如果表達式A大於表達式B,否則FALSE。 |
A >= B |
所有基本類型 |
TRUE,如果表達式A大於或等於表達式B,否則FALSE。 |
A IS NULL |
所有類型 |
TRUE,如果表達式的計算結果爲NULL,否則FALSE。 |
A IS NOT NULL |
所有類型 |
FALSE,如果表達式A的計算結果爲NULL,否則TRUE。 |
A LIKE B |
字符串 |
TRUE,如果字符串模式A匹配到B,否則FALSE。 |
A RLIKE B |
字符串 |
NULL,如果A或B爲NULL;TRUE,如果A任何子字符串匹配Java正則表達式B;否則FALSE。 |
A REGEXP B |
字符串 |
等同於RLIKE. |
示例
假設employee表由字段:Id, Name,Salary, Designation,和Dept組成,如下圖所示。生成一個查詢檢索員工詳細信息 - ID爲1205。
+-----+--------------+--------+-----------------------+---
| Id | Name | Salary | Designation |Dept |
+-----+--------------+------------------------------------+---
|1201 |Gopal | 45000 | Technical manager | TP |
|1202 |Manisha | 45000 | Proofreader | PR |
|1203 |Masthanvali | 40000 | Technical writer | TP |
|1204 |Krian | 40000 | Hr Admin | HR |
|1205 |Kranthi | 30000 | Op Admin | Admin|
+-----+--------------+--------+-----------------------+---
以下查詢執行檢索使用上述表中的僱員的詳細信息:
hive>SELECT* FROM employee WHEREId=1205;
成功執行的查詢,有以下結果:
+-----+-----------+-----------+----------------------+
| ID | Name | Salary | Designation | Dept |
+-----+---------------+-------+----------------------+
|1205 | Kranthi | 30000 | Op Admin | Admin |
+-----+-----------+-----------+----------------------+
下面的查詢執行以檢索薪水大於或等於40000盧比的僱員的詳細信息。
hive>SELECT* FROM employee WHERESalary>=40000;
成功執行的查詢,有以下回應:
+-----+------------+--------+------------------------+------+
| ID | Name | Salary | Designation | Dept |
+-----+------------+--------+------------------------+------+
|1201 |Gopal | 45000 | Technical manager | TP |
|1202 | Manisha | 45000 | Proofreader | PR
|1203 |Masthanvali| 40000 | Technicalwriter | TP |
|1204 |Krian | 40000 | Hr Admin | HR |
+-----+------------+--------+------------------------+------+
算術運算符:支持的操作數各種常見的算術運算。返回數字類型。下表描述了在Hive中可用的算術運算符:
運算符 |
操作 |
描述 |
A + B |
所有數字類型 |
A加B的結果 |
A - B |
所有數字類型 |
A減去B的結果 |
A * B |
所有數字類型 |
A乘以B的結果 |
A / B |
所有數字類型 |
A除以B的結果 |
A % B |
所有數字類型 |
A除以B.產生的餘數 |
A & B |
所有數字類型 |
A和B的按位與結果 |
A | B |
所有數字類型 |
A和B的按位或結果 |
A ^ B |
所有數字類型 |
A和B的按位異或結果 |
~A |
所有數字類型 |
A按位非的結果 |
示例
下面的查詢相加兩個數字,20和30。
hive>SELECT20+30 ADD FROM temp;
在成功執行查詢後,有以下回應:
+--------+
| ADD |
+--------+
| 50 |
+--------+
邏輯運算符
運算符是邏輯表達式。所有這些返回TRUE或FALSE。
運算符 |
操作 |
描述 |
A AND B |
boolean |
TRUE,如果A和B都是TRUE,否則FALSE。 |
A && B |
boolean |
類似於 A AND B. |
A OR B |
boolean |
TRUE,如果A或B或兩者都是TRUE,否則FALSE。 |
A || B |
boolean |
類似於 A OR B. |
NOT A |
boolean |
TRUE,如果A是FALSE,否則FALSE。 |
!A |
boolean |
類似於 NOT A. |
示例
下面的查詢用於檢索部門是TP並且工資超過40000盧比的員工詳細信息。
hive>SELECT* FROM employee WHERESalary>40000&&Dept=TP;
成功執行查詢後,能看到以下回應:
+------+--------------+-----------+---------------—--+-------+
| ID | Name | Salary | Designation | Dept |
+------+--------------+-----------+------------------+-------+
|1201 | Gopal | 45000 | Technical manager|TP |
+------+--------------+-----------+------------------+-------+
複雜的運算符
這些運算符提供一個表達式來接入複雜類型的元素。
運算符 |
操作 |
描述 |
A[n] |
A是一個數組,n是一個int |
它返回數組A的第n個元素,第一個元素的索引0。 |
M[key] |
M 是一個 Map<K, V>並 key 的類型爲K |
它返回對應於映射中關鍵字的值。 |
S.x |
S 是一個結構 |
它返回S的s字段 |
1.10Hive內置函數
Hive支持以下內置函數:
返回類型 |
簽名 |
描述 |
BIGINT |
round(double a) |
返回BIGINT最近的double值。 |
BIGINT |
floor(double a) |
返回最大BIGINT值等於或小於double。 |
BIGINT |
ceil(double a) |
它返回最小BIGINT值等於或大於double。 |
double |
rand(), rand(int seed) |
它返回一個隨機數,從行改變到行。 |
string |
concat(string A, string B,...) |
它返回從A後串聯B產生的字符串 |
string |
substr(string A, int start) |
它返回一個起始,從起始位置的子字符串,直到A.結束 |
string |
substr(string A, int start, int length) |
返回從給定長度的起始start位置開始的字符串。 |
string |
upper(string A) |
它返回從轉換的所有字符爲大寫產生的字符串。 |
string |
ucase(string A) |
和上面的一樣 |
string |
lower(string A) |
它返回轉換B的所有字符爲小寫產生的字符串。 |
string |
lcase(string A) |
和上面的一樣 |
string |
trim(string A) |
它返回字符串從A.兩端修剪空格的結果 |
string |
ltrim(string A) |
它返回A從一開始修整空格產生的字符串(左手側) |
string |
rtrim(string A) |
rtrim(string A),它返回A從結束脩整空格產生的字符串(右側) |
string |
regexp_replace(string A, string B, string C) |
它返回從替換所有子在B結果配合C.在Java正則表達式語法的字符串 |
int |
size(Map<K.V>) |
它返回在映射類型的元素的數量。 |
int |
size(Array<T>) |
它返回在數組類型元素的數量。 |
value of <type> |
cast(<expr> as <type>) |
它把表達式的結果expr<類型>如cast('1'作爲BIGINT)代表整體轉換爲字符串'1'。如果轉換不成功,返回的是NULL。 |
string |
from_unixtime(int unixtime) |
轉換的秒數從Unix紀元(1970-01-0100:00:00 UTC)代表那一刻,在當前系統時區的時間戳字符的串格式:"1970-01-01 00:00:00" |
string |
to_date(string timestamp) |
返回一個字符串時間戳的日期部分:to_date("1970-01-01 00:00:00") = "1970-01-01" |
int |
year(string date) |
返回年份部分的日期或時間戳字符串:year("1970-01-01 00:00:00") = 1970, year("1970-01-01") = 1970 |
int |
month(string date) |
返回日期或時間戳記字符串月份部分:month("1970-11-01 00:00:00") = 11, month("1970-11-01") = 11 |
int |
day(string date) |
返回日期或時間戳記字符串當天部分:day("1970-11-01 00:00:00") = 1, day("1970-11-01") = 1 |
string |
get_json_object(string json_string, string path) |
提取從基於指定的JSON路徑的JSON字符串JSON對象,並返回提取的JSON字符串的JSON對象。如果輸入的JSON字符串無效,返回NULL。 |
示例;
round() 函數
hive>SELECT round(2.6)from temp;
成功執行的查詢,能看到以下回應:
2.0
floor() 函數
hive>SELECT floor(2.6)from temp;
2.0
聚合函數
Hive支持以下內置聚合函數。這些函數的用法類似SQL聚合函數。
返回類型 |
簽名 |
描述 |
BIGINT |
count(*), count(expr), |
count(*) - 返回檢索行的總數。 |
DOUBLE |
sum(col), sum(DISTINCT col) |
返回該組或該組中的列的不同值的分組和所有元素的總和。 |
DOUBLE |
avg(col), avg(DISTINCT col) |
返回上述組或該組中的列的不同值的元素的平均值。 |
DOUBLE |
min(col) |
返回該組中的列的最小值。 |
DOUBLE |
max(col) |
返回該組中的列的最大值。 |
1.11Hive視圖和索引
和SQL類似,可根據用戶的需求創建視圖,將任何結果集數據保存爲一個視圖。
創建一個視圖
可以創建一個視圖,在執行SELECT語句的時候。語法如下:
CREATE VIEW [IFNOT EXISTS] view_name [(column_name [COMMENT column_comment], ...) ]
[COMMENTtable_comment]
AS SELECT ...
示例
設employee表擁有如下字段:Id, Name, Salary, Designation和 Dept。生成一個查詢檢索工資超過30000盧比的員工詳細信息,我們把結果存儲在一個名爲視圖 emp_30000.
+------+--------------+-----------+------------------+-------+
| ID | Name | Salary | Designation | Dept |
+------+--------------+-----------+------------------+-------+
|1201 | Gopal | 45000 |Technical manager |TP |
|1202 | Manisha | 45000 | Proofreader | PR |
|1203 | Masthanvali | 40000 | Technical writer |TP |
|1204 | Krian | 40000 | Hr Admin | HR |
|1205 | Kranthi | 30000 | Op Admin | Admin
+------+--------------+-----------+------------------+-------+
下面使用上述業務情景查詢檢索員的工詳細信息:
hive> CREATE VIEWemp_30000 AS
> SELECT * FROM employee
> WHERE salary>30000;
刪除一個視圖
語法:DROP VIEW view_name
創建索引
索引是一個表上的一個特定列的指針。創建索引意味着創建表上的一個特定列的指針。語法如下:
CREATE INDEXindex_name
ON TABLEbase_table_name (col_name, ...)
AS'index.handler.class.name'
[WITH DEFERREDREBUILD]
[IDXPROPERTIES(property_name=property_value, ...)]
[IN TABLEindex_table_name]
[PARTITIONED BY(col_name, ...)]
[
[ ROW FORMAT ...] STORED AS ...
| STORED BY ...
]
[LOCATIONhdfs_path]
[TBLPROPERTIES(...)]
示例,使用之前的字段 Id, Name, Salary, Designation,和 Dept創建一個名爲index_salary的索引,對employee表的salary列索引。
下面的查詢創建一個索引:
hive> CREATE INDEXinedx_salary ON TABLE employee(salary)
> AS'org.apache.hadoop.hive.ql.index.compact.CompactIndexHandler';
這是一個指向salary列。如果列被修改,變更使用的索引值存儲。
刪除索引
用來刪除索引的語法:
DROP INDEX <index_name> ON<table_name>
下面的查詢刪除名爲index_salary索引:
hive> DROP INDEXindex_salary ON employee;
1.12Hive QL SELECT WHERE子句
SELECT語句用來從表中檢索的數據。 WHERE子句中的工作原理類似於一個條件。它使用這個條件過濾數據,並返回給出一個有限的結果。內置運算符和函數產生一個表達式,滿足該條件並從表中select出來。
SELECT查詢的語法;
查詢檢索薪水大於30000的員工信息;
hive> SELECT * FROMemployee WHERE salary>30000;
1.13Hive QL SELECT ORDER BY子句
ORDER BY子句用於檢索基於一列的細節並設置排序結果按升序或降序排列。
ORDER BY子句的語法;
例如,有員工表;
+------+--------------+----------+------------------+--------+
| ID | Name | Salary | Designation | Dept |
+------+--------------+----------+------------------+--------+
|1201 | Gopal | 45000 |Technical manager |TP |
|1202 | Manisha | 45000 | Proofreader | PR |
|1203 | Masthanvali | 40000 | Technical writer |TP |
|1204 | Krian | 40000 | Hr Admin | HR |
|1205 | Kranthi | 30000 | Op Admin | Admin |
+------+--------------+----------+------------------+--------+
hive> SELECTId,Name,Dept FROM employee ORDER BY DEPT;
得到查詢結果
+------+--------------+----------+-----------------+--------+
| ID | Name | Salary | Designation | Dept |
+------+--------------+----------+-----------------+--------+
|1205 | Kranthi | 30000 | Op Admin | Admin |
|1204 | Krian | 40000 | Hr Admin | HR |
|1202 | Manisha | 45000 | Proofreader | PR |
|1201 | Gopal | 45000 |Technical manager|TP |
|1203 | Masthanvali | 40000 | Technical writer|TP |
+------+--------------+----------+-----------------+--------+
1.14Hive QL SELECT GROUP BY子句
GROUP BY子句用於分類所有記錄結果的特定集合列,用來查詢一組記錄。
GROUP BY子句的語法:
同樣的,上述員工表,
hive> SELECTDept,count(*) FROM employee GROUP BYDEPT;
查詢以檢索每個部門的員工數量。
+------+--------------+
| Dept |Count(*) |
+------+--------------+
|Admin | 1 |
|PR | 2 |
|TP | 3 |
+------+--------------+
1.15Hive QL SELECT JOIN子句
JOIN子句通過共同值組合來自兩個表的特定字段。它是從數據庫中的兩個或更多的表組合的記錄。
語法;
join_table:
table_reference JOIN table_factor[join_condition]
| table_reference{LEFT|RIGHT|FULL}[OUTER] JOINtable_reference
join_condition
| table_referenceLEFT SEMI JOIN table_reference join_condition
| table_referenceCROSS JOIN table_reference[join_condition]
示例,CUSTOMERS表
+----+----------+-----+-----------+----------+
| ID | NAME | AGE | ADDRESS | SALARY |
+----+----------+-----+-----------+----------+
| 1 | Ramesh | 32 | Ahmedabad | 2000.00 |
| 2 | Khilan | 25 | Delhi | 1500.00 |
| 3 | kaushik | 23 | Kota | 2000.00 |
| 4 | Chaitali | 25 | Mumbai | 6500.00 |
| 5 | Hardik | 27 |Bhopal | 8500.00 |
| 6 | Komal | 22 | MP | 4500.00 |
| 7 | Muffy | 24 | Indore | 10000.00 |
+----+----------+-----+-----------+----------+
另一個ORDERS表
+-----+---------------------+-------------+--------+
|OID | DATE | CUSTOMER_ID |AMOUNT |
+-----+---------------------+-------------+--------+
| 102 |2009-10-08 00:00:00 | 3 |3000 |
| 100 |2009-10-08 00:00:00 | 3 |1500 |
| 101 |2009-11-20 00:00:00 | 2 |1560 |
| 103 |2008-05-20 00:00:00 | 4 |2060 |
+-----+---------------------+-------------+--------+
其中有不同類型的聯接;JOIN、LEFT OUTER JOIN、RIGHT OUTER JOIN、FULL OUTER JOIN。
JOIN:
JOIN子句用於合併和檢索來自多個表中的記錄。 JOIN和SQL OUTER JOIN類似。連接條件是使用主鍵和表的外鍵。
hive> SELECT c.ID, c.NAME, c.AGE, o.AMOUNT
> FROM CUSTOMERS c JOINORDERS o
> ON(c.ID= o.CUSTOMER_ID);
查詢結果;
+----+----------+-----+--------+
| ID | NAME | AGE | AMOUNT |
+----+----------+-----+--------+
| 3 | kaushik | 23 | 3000 |
| 3 | kaushik | 23 | 1500 |
| 2 | Khilan | 25 | 1560 |
| 4 | Chaitali | 25 | 2060 |
+----+----------+-----+--------+
LEFT OUTER JOIN
HiveQL LEFT OUTER JOIN返回所有行左表,即使是在正確的表中沒有匹配。這意味着,如果ON子句匹配的右表0(零)記錄,JOIN還是返回結果行,但在右表中的每一列爲NULL。
例如以下LEFT OUTER JOIN用法
hive> SELECT c.ID, c.NAME, o.AMOUNT, o.DATE
> FROM CUSTOMERS c
> LEFT OUTER JOIN ORDERS o
> ON(c.ID= o.CUSTOMER_ID);
查詢結果;
+----+----------+--------+---------------------+
| ID | NAME | AMOUNT | DATE |
+----+----------+--------+---------------------+
| 1 | Ramesh | NULL | NULL |
| 2 | Khilan | 1560 | 2009-11-20 00:00:00 |
| 3 | kaushik | 3000 | 2009-10-08 00:00:00 |
| 3 | kaushik | 1500 | 2009-10-08 00:00:00 |
| 4 | Chaitali | 2060 | 2008-05-20 00:00:00 |
| 5 | Hardik | NULL | NULL |
| 6 | Komal | NULL | NULL |
| 7 | Muffy | NULL | NULL |
+----+----------+--------+---------------------+
RIGHT OUTER JOIN
HiveQL RIGHT OUTER JOIN返回右邊表的所有行,即使有在左表中沒有匹配。如果ON子句的左表匹配0(零)的記錄,JOIN結果返回一行,但在左表中的每一列爲NULL。
hive> SELECT c.ID, c.NAME, o.AMOUNT, o.DATE
> FROM CUSTOMERS c
> RIGHT OUTER JOIN ORDERS o
> ON(c.ID= o.CUSTOMER_ID);
查詢結果:
+------+----------+--------+---------------------+
| ID | NAME | AMOUNT | DATE |
+------+----------+--------+---------------------+
| 3 | kaushik | 3000 | 2009-10-08 00:00:00 |
| 3 | kaushik | 1500 | 2009-10-08 00:00:00 |
| 2 | Khilan | 1560 | 2009-11-20 00:00:00 |
| 4 | Chaitali | 2060 | 2008-05-20 00:00:00 |
+------+----------+--------+---------------------+
FULL OUTER JOIN
HiveQL FULL OUTER JOIN結合了左邊,並且滿足JOIN條件合適外部表的記錄。連接表包含兩個表的所有記錄,或兩側缺少匹配結果那麼使用NULL值填補。
+------+----------+--------+---------------------+
| ID | NAME | AMOUNT | DATE |
+------+----------+--------+---------------------+
| 1 | Ramesh | NULL | NULL |
| 2 | Khilan | 1560 | 2009-11-20 00:00:00 |
| 3 | kaushik | 3000 | 2009-10-08 00:00:00 |
| 3 | kaushik | 1500 | 2009-10-08 00:00:00 |
| 4 | Chaitali | 2060 | 2008-05-20 00:00:00 |
| 5 | Hardik | NULL | NULL |
| 6 | Komal | NULL | NULL |
| 7 | Muffy | NULL | NULL |
| 3 | kaushik | 3000 | 2009-10-08 00:00:00 |
| 3 | kaushik | 1500 | 2009-10-08 00:00:00 |
| 2 | Khilan | 1560 | 2009-11-20 00:00:00 |
| 4 | Chaitali | 2060 | 2008-05-20 00:00:00 |
+------+----------+--------+---------------------+
1.16從SQL到HiveQL應注意的點
1、Hive不支持等值連接
• SQL中對兩表內聯可以寫成:
•select * from dual a,dual bwhere a.key = b.key;
•Hive中應爲
•select * from dual a joindual b on a.key = b.key;
2、分號字符
•分號是SQL語句結束標記,在HiveQL中也是,但是在HiveQL中,對分號的識別沒有那麼智慧,例如:
•selectconcat(key,concat(';',key)) from dual;
•但HiveQL在解析語句時提示:
FAILED: Parse Error: line 0:-1 mismatched input '<EOF>' expecting ) infunction specification
•解決的辦法是,使用分號的八進制的ASCII碼進行轉義,那麼上述語句應寫成:
•selectconcat(key,concat('\073',key)) from dual;
3、IS[NOT] NULL
•SQL中null代表空值, 值得警惕的是,在HiveQL中String類型的字段若是空(empty)字符串,即長度爲0,而對它進行ISNULL的判斷結果是False.