一、Hive分區
(1)Hive 分區partition:必須在表定義時指定對應的partition字段
a、單分區建表語句:
create table day_table (id int, content string) partitioned by (dt string);
單分區表,按天分區,在表結構中存在id,content,dt三列。
以dt爲文件夾區分
b、 雙分區建表語句:
create table day_hour_table (id int, content string) partitioned by (dt string, hour string);
雙分區表,按天和小時分區,在表結構中新增加了dt和hour兩列。
先以dt爲文件夾,再以hour子文件夾區分
(2)Hive添加分區表語法(表已創建,在此基礎上添加分區)
ALTER TABLE table_name ADD [IF NOT EXISTS] PARTITION partition_spec [LOCATION 'location1'] partition_spec [LOCATION 'location2'] ...;
partition_spec:
: (partition_column = partition_col_value, partition_column = partition_col_value, ...)
例:
ALTER TABLE day_table ADD PARTITION (dt='2008-08-08', hour='08')
(3)Hive刪除分區語法
ALTER TABLE table_name DROP partition_spec, partition_spec,...
partition_spec:
: (partition_column = partition_col_value, partition_column = partition_col_value, ...)
用戶可以用 ALTER TABLE DROP PARTITION 來刪除分區。
內部表中、對應分區的元數據和數據將被一併刪除。
例:
ALTER TABLE day_hour_table DROP PARTITION (dt='2008-08-08', hour='09');
(4)Hive向指定分區添加數據語法
LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE tablename [PARTITION (partcol1=val1, partcol2=val2 ...)]
例:
LOAD DATA INPATH '/user/pv.txt' INTO TABLE day_hour_table PARTITION(dt='2008-08- 08', hour='08');
LOAD DATA local INPATH '/user/hua/*' INTO TABLE day_hour partition(dt='2010-07- 07');
當數據被加載至表中時,不會對數據進行任何轉換。Load操作只是將數據複製至Hive表對應的位置。數據加載時在表下自動創建一個目錄
(5)Hive查詢執行分區語法
SELECT day_table.* FROM day_table WHERE day_table.dt>= '2008-08-08';
分區表的意義在於優化查詢。查詢時儘量利用分區字段。如果不使用分區字段,就會全部掃描。
Hive查詢表的分區信息語法:
SHOW PARTITIONS day_hour_table;
預先導入分區數據,但是無法識別怎麼辦
Msck repair table tablename
直接添加分區
二、Hive SerDe
(1)作用
SerDe 用於做序列化和反序列化,構建在數據存儲和執行引擎之間,對兩者實現解耦,Hive通過ROW FORMAT DELIMITED以及SERDE進行內容的讀寫
row_format
: DELIMITED
[FIELDS TERMINATED BY char [ESCAPED BY char]]
[COLLECTION ITEMS TERMINATED BY char]
[MAP KEYS TERMINATED BY char]
[LINES TERMINATED BY char]
: SERDE serde_name [WITH SERDEPROPERTIES (property_name=property_value, property_name=property_value, ...)]
(2)Hive正則匹配
CREATE TABLE logtbl (
host STRING,
identity STRING,
t_user STRING,
time STRING,
request STRING,
referer STRING,
agent STRING)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe'
WITH SERDEPROPERTIES (
"input.regex" = "([^ ]*) ([^ ]*) ([^ ]*) \\[(.*)\\] \"(.*)\" (-|[0-9]*) (-|[0-9]*)"
)
STORED AS TEXTFILE;
三、Hive Beeline
(1)作用
Beeline 要與HiveServer2配合使用
服務端啓動hiveserver2
客戶的通過beeline兩種方式連接到hive:
1、beeline -u jdbc:hive2://localhost:10000/default -n root
2、beeline
beeline> !connect jdbc:hive2://<host>:<port>/<db>;auth=noSasl root 123
默認 用戶名、密碼不驗證
四、Hive JDBC
(1)Hive JDBC運行方式
服務端啓動hiveserver2後,在java代碼中通過調用hive的jdbc訪問默認端口10000進行連接、訪問
(2)代碼
五、常用函數
(1)關係運算符
(1)A LIKE B 字符串 如 果A或B值爲”NULL”,結果返回”NULL”。字符串A與B通過sql進行匹配,如果相符返回TRUE,不符返回FALSE。B字符串中 的”_”代表任一字符,”%”則代表多個任意字符。例如: (‘foobar’ like ‘foo’)返回FALSE,( ‘foobar’ like ‘foo_ _ _’或者 ‘foobar’ like ‘foo%’)則返回TURE
(2)A RLIKE B 字符串 如 果A或B值爲”NULL”,結果返回”NULL”。字符串A與B通過java進行匹配,如果相符返回TRUE,不符返回FALSE。例如:( ‘foobar’ rlike ‘foo’)返回FALSE,(’foobar’ rlike ‘^f.*r$’ )返回TRUE。
(3)A REGEXP B 字符串 與RLIKE相同。
(2) 算術運算符
(1)A & B 所有數字類型 運算符查看兩個參數的二進制表示法的值,並執行按位”與”操作。兩個表達式的一位均爲1時,則結果的該位爲 1。否則,結果的該位爲 0。
A|B 所有數字類型 運算符查看兩個參數的二進制表示法的值,並執行按位”或”操作。只要任一表達式的一位爲 1,則結果的該位爲 1。否則,結果的該位爲 0。
(2)A ^ B 所有數字類型 運算符查看兩個參數的二進制表示法的值,並執行按位”異或”操作。當且僅當只有一個表達式的某位上爲 1 時,結果的該位才爲 1。否則結果的該位爲 0。
(3)~A 所有數字類型 對一個表達式執行按位”非”(取反)。
(3)複雜類型函數
(1)map (key1, value1, key2, value2, …) 通過指定的鍵/值對,創建一個map。
(2)struct (val1, val2, val3, …) 通過指定的字段值,創建一個結構。結構字段名稱將COL1,COL2,…
(3)array (val1, val2, …) 通過指定的元素,創建一個數組。
對複雜類型函數操作:
函數 |
類型 |
說明 |
A[n] |
A是一個數組,n爲int型 |
返回數組A的第n個元素,第一個元素的索引爲0。如果A數組爲['foo','bar'],則A[0]返回’foo’和A[1]返回”bar”。 |
M[key] |
M是Map<K, V>,關鍵K型 |
返回關鍵值對應的值,例如mapM爲 \{‘f’ -> ‘foo’, ‘b’ -> ‘bar’, ‘all’ -> ‘foobar’\},則M['all'] 返回’foobar’。 |
S.x |
S爲struct |
返回結構x字符串在結構S中的存儲位置。如 foobar \{int foo, int bar\} foobar.foo的領域中存儲的整數。 |
(4)收集函數
返回類型 |
函數 |
說明 |
int |
size(Map<K.V>) |
返回的map類型的元素的數量 |
int |
size(Array<T>) |
返回數組類型的元素數量 |
(5)類型轉換函數
返回類型 |
函數 |
說明 |
指定 “type” |
cast(expr as <type>) |
類型轉換。例如將字符”1″轉換爲整數:cast(’1′ as bigint),如果轉換失敗返回NULL。 |
(6)數學函數
返回類型 |
函數 |
說明 |
BIGINT |
round(double a) |
四捨五入 |
DOUBLE |
round(double a, int d) |
小數部分d位之後數字四捨五入,例如round(21.263,2),返回21.26 |
BIGINT |
floor(double a) |
對給定數據進行向下舍入最接近的整數。例如floor(21.2),返回21。 |
BIGINT |
ceil(double a), ceiling(double a) |
將參數向上舍入爲最接近的整數。例如ceil(21.2),返回23. |
double |
rand(), rand(int seed) |
返回大於或等於0且小於1的平均分佈隨機數(依重新計算而變) |
double |
exp(double a) |
返回e的n次方 |
double |
ln(double a) |
返回給定數值的自然對數 |
double |
log10(double a) |
返回給定數值的以10爲底自然對數 |
double |
log2(double a) |
返回給定數值的以2爲底自然對數 |
double |
log(double base, double a) |
返回給定底數及指數返回自然對數 |
double |
pow(double a, double p) power(double a, double p) |
返回某數的乘冪 |
double |
sqrt(double a) |
返回數值的平方根 |
string |
bin(BIGINT a) |
返回二進制格式 |
string |
hex(BIGINT a) hex(string a) |
將整數或字符轉換爲十六進制格式 |
string |
unhex(string a) |
十六進制字符轉換由數字表示的字符。 |
string |
conv(BIGINT num, int from_base, int to_base) |
將 指定數值,由原來的度量體系轉換爲指定的試題體系。例如CONV(‘a’,16,2),返回。參考:’1010′ http://dev.mysql.com/doc/refman/5.0/en/mathematical-functions.html#function_conv |
double |
abs(double a) |
取絕對值 |
int double |
pmod(int a, int b) pmod(double a, double b) |
返回a除b的餘數的絕對值 |
double |
sin(double a) |
返回給定角度的正弦值 |
double |
asin(double a) |
返回x的反正弦,即是X。如果X是在-1到1的正弦值,返回NULL。 |
double |
cos(double a) |
返回餘弦 |
double |
acos(double a) |
返回X的反餘弦,即餘弦是X,,如果-1<= A <= 1,否則返回null. |
int double |
positive(int a) positive(double a) |
返回A的值,例如positive(2),返回2。 |
int double |
negative(int a) negative(double a) |
返回A的相反數,例如negative(2),返回-2。 |
(7)日期函數
返回類型 |
函數 |
說明 |
string |
from_unixtime(bigint unixtime[, string format]) |
UNIX_TIMESTAMP參數表示返回一個值’YYYY- MM – DD HH:MM:SS’或YYYYMMDDHHMMSS.uuuuuu格式,這取決於是否是在一個字符串或數字語境中使用的功能。該值表示在當前的時區。 |
bigint |
unix_timestamp() |
如果不帶參數的調用,返回一個Unix時間戳(從’1970- 01 – 0100:00:00′到現在的UTC秒數)爲無符號整數。 |
bigint |
unix_timestamp(string date) |
指定日期參數調用UNIX_TIMESTAMP(),它返回參數值’1970- 01 – 0100:00:00′到指定日期的秒數。 |
bigint |
unix_timestamp(string date, string pattern) |
指定時間輸入格式,返回到1970年秒數:unix_timestamp(’2009-03-20′, ‘yyyy-MM-dd’) = 1237532400 |
string |
to_date(string timestamp) |
返回時間中的年月日: to_date(“1970-01-01 00:00:00″) = “1970-01-01″ |
string |
to_dates(string date) |
給定一個日期date,返回一個天數(0年以來的天數) |
int |
year(string date) |
返回指定時間的年份,範圍在1000到9999,或爲”零”日期的0。 |
int |
month(string date) |
返回指定時間的月份,範圍爲1至12月,或0一個月的一部分,如’0000-00-00′或’2008-00-00′的日期。 |
int |
day(string date) dayofmonth(date) |
返回指定時間的日期 |
int |
hour(string date) |
返回指定時間的小時,範圍爲0到23。 |
int |
minute(string date) |
返回指定時間的分鐘,範圍爲0到59。 |
int |
second(string date) |
返回指定時間的秒,範圍爲0到59。 |
int |
weekofyear(string date) |
返回指定日期所在一年中的星期號,範圍爲0到53。 |
int |
datediff(string enddate, string startdate) |
兩個時間參數的日期之差。 |
int |
date_add(string startdate, int days) |
給定時間,在此基礎上加上指定的時間段。 |
int |
date_sub(string startdate, int days) |
給定時間,在此基礎上減去指定的時間段。 |
(8) 條件函數
返回類型 |
函數 |
說明 |
T |
if(boolean testCondition, T valueTrue, T valueFalseOrNull) |
判斷是否滿足條件,如果滿足返回一個值,如果不滿足則返回另一個值。 |
T |
COALESCE(T v1, T v2, …) |
返回一組數據中,第一個不爲NULL的值,如果均爲NULL,返回NULL。 |
T |
CASE a WHEN b THEN c [WHEN d THEN e]* [ELSE f] END |
當a=b時,返回c;當a=d時,返回e,否則返回f。 |
T |
CASE WHEN a THEN b [WHEN c THEN d]* [ELSE e] END |
當值爲a時返回b,當值爲c時返回d。否則返回e。 |
(9)字符函數
返回類型 |
函數 |
說明 |
int |
length(string A) |
返回字符串的長度 |
string |
reverse(string A) |
返回倒序字符串 |
string |
concat(string A, string B…) |
連接多個字符串,合併爲一個字符串,可以接受任意數量的輸入字符串 |
string |
concat_ws(string SEP, string A, string B…) |
鏈接多個字符串,字符串之間以指定的分隔符分開。 |
string |
substr(string A, int start) substring(string A, int start) |
從文本字符串中指定的起始位置後的字符。 |
string |
substr(string A, int start, int len) substring(string A, int start, int len) |
從文本字符串中指定的位置指定長度的字符。 |
string |
upper(string A) ucase(string A) |
將文本字符串轉換成字母全部大寫形式 |
string |
lower(string A) lcase(string A) |
將文本字符串轉換成字母全部小寫形式 |
string |
trim(string A) |
刪除字符串兩端的空格,字符之間的空格保留 |
string |
ltrim(string A) |
刪除字符串左邊的空格,其他的空格保留 |
string |
rtrim(string A) |
刪除字符串右邊的空格,其他的空格保留 |
string |
regexp_replace(string A, string B, string C) |
字符串A中的B字符被C字符替代 |
string |
regexp_extract(string subject, string pattern, int index) |
通過下標返回正則表達式指定的部分。regexp_extract(‘foothebar’, ‘foo(.*?)(bar)’, 2) returns ‘bar.’ |
string |
parse_url(string urlString, string partToExtract [, string keyToExtract]) |
返回URL指定的部分。parse_url(‘http://facebook.com/path1/p.php?k1=v1&k2=v2#Ref1′, ‘HOST’) 返回:’facebook.com’ |
string |
get_json_object(string json_string, string path) |
select a.timestamp, get_json_object(a.appevents, ‘$.eventid’), get_json_object(a.appenvets, ‘$.eventname’) from log a; |
string |
space(int n) |
返回指定數量的空格 |
string |
repeat(string str, int n) |
重複N次字符串 |
int |
ascii(string str) |
返回字符串中首字符的數字值 |
string |
lpad(string str, int len, string pad) |
返回指定長度的字符串,給定字符串長度小於指定長度時,由指定字符從左側填補。 |
string |
rpad(string str, int len, string pad) |
返回指定長度的字符串,給定字符串長度小於指定長度時,由指定字符從右側填補。 |
array |
split(string str, string pat) |
將字符串轉換爲數組。 |
int |
find_in_set(string str, string strList) |
返回字符串str第一次在strlist出現的位置。如果任一參數爲NULL,返回NULL;如果第一個參數包含逗號,返回0。 |
array<array<string>> |
sentences(string str, string lang, string locale) |
將字符串中內容按語句分組,每個單詞間以逗號分隔,最後返回數組。 例如sentences(‘Hello there! How are you?’) 返回:( (“Hello”, “there”), (“How”, “are”, “you”) ) |
array<struct<string,double>> |
ngrams(array<array<string>>, int N, int K, int pf) |
SELECT ngrams(sentences(lower(tweet)), 2, 100 [, 1000]) FROM twitter; |
array<struct<string,double>> |
context_ngrams(array<array<string>>, array<string>, int K, int pf) |
SELECT context_ngrams(sentences(lower(tweet)), array(null,null), 100, [, 1000]) FROM twitter; |
(10)內置的聚合函數(UDAF)
返回類型 |
函數 |
說明 |
bigint |
count(*) , count(expr), count(DISTINCT expr[, expr_., expr_.]) |
返回記錄條數。 |
double |
sum(col), sum(DISTINCT col) |
求和 |
double |
avg(col), avg(DISTINCT col) |
求平均值 |
double |
min(col) |
返回指定列中最小值 |
double |
max(col) |
返回指定列中最大值 |
double |
var_pop(col) |
返回指定列的方差 |
double |
var_samp(col) |
返回指定列的樣本方差 |
double |
stddev_pop(col) |
返回指定列的偏差 |
double |
stddev_samp(col) |
返回指定列的樣本偏差 |
double |
covar_pop(col1, col2) |
兩列數值協方差 |
double |
covar_samp(col1, col2) |
兩列數值樣本協方差 |
double |
corr(col1, col2) |
返回兩列數值的相關係數 |
double |
percentile(col, p) |
返回數值區域的百分比數值點。0<=P<=1,否則返回NULL,不支持浮點型數值。 |
array<double> |
percentile(col, array(p~1,,\ [, p,,2,,]…)) |
返回數值區域的一組百分比值分別對應的數值點。0<=P<=1,否則返回NULL,不支持浮點型數值。 |
(11)內置表生成函數(UDTF)
返回類型 |
函數 |
說明 |
數組 |
explode(array<TYPE> a) |
數組一條記錄中有多個參數,將參數拆分,每個參數生成一列。 |
|
json_tuple |
get_json_object 語句:select a.timestamp, get_json_object(a.appevents, ‘$.eventid’), get_json_object(a.appenvets, ‘$.eventname’) from log a; json_tuple語句: select a.timestamp, b.* from log a lateral view json_tuple(a.appevent, ‘eventid’, ‘eventname’) b as f1, f2 |
(12)自定義函數
自定義函數包括三種UDF、UDAF、UDTF
- UDF(User-Defined-Function) 一進一出
- UDAF(User- Defined Aggregation Funcation) 聚集函數,多進一出。Count/max/min
- UDTF(User-Defined Table-Generating Functions)  一進多出,如lateral view explore()
使用方式 :在HIVE會話中add 自定義函數的jar文件,然後創建function繼而使用函數
(13)常用函數
trim() # 去除兩邊空格
lower(), upper() # 大小寫轉換
cast(expr as type) # 類型轉換
length() # 返回字符串長度
reverse() # 反轉字符
substring(string A, int start, int len) # 字符串截取
concat(string A, string B, string C, ...) # 字符串連接
concat_ws(string sep, string A, string B, string C, ...) # 自定義分隔符sep的字符串連接
str_to_map(string A, string item_pat, string dict_pat) # 將字符串轉爲map
split(string str, string pat) # 按照pat字符串分割str,返回分割後的字符串數組
coalesce(v1, v2, v3, ...) # 返回列表中第一個非空元素,如果所有值都爲空,則返回null
from_unixtime(unix_timestamp(), 'yyyy-MM-dd HH:mm:ss') # 返回當前時間
instr(string str, string search_str) # 返回第二個參數在待查找字符串中的位置(找不到返回0)
map_keys(map m) # 提取出map的key, 返回key的array
datediff(date1, date2) # 日期比較函數,返回相差天數,datediff('${cur_date},d)
explode(colname) # explode就是將hive一行中複雜的array或者map結構拆分成多行
六、UDF 開發
1、UDF函數可以直接應用於select語句,對查詢結構做格式化處理後,再輸出內容。
2、編寫UDF函數的時候需要注意一下幾點:
- 自定義UDF需要繼承org.apache.hadoop.hive.ql.UDF。
- 需要實現evaluate函數,evaluate函數支持重載。
3、步驟
- 把程序打包放到目標機器上去;
- 進入hive客戶端,添加jar包:hive>add jar /run/jar/udf_test.jar;
- 創建臨時函數:hive>CREATE TEMPORARY FUNCTION add_example AS 'hive.udf.Add';
- 查詢HQL語句:
SELECT add_example(8, 9) FROM scores;
SELECT add_example(scores.math, scores.art) FROM scores;
SELECT add_example(6, 7, 8, 6.8) FROM scores;
- 銷燬臨時函數:hive> DROP TEMPORARY FUNCTION add_example;
七、UDAF 自定義集函數
多行進一行出,如sum()、min(),用在group by時
1.必須繼承
org.apache.hadoop.hive.ql.exec.UDAF(函數類繼承)
org.apache.hadoop.hive.ql.exec.UDAFEvaluator(內部類Evaluator實現UDAFEvaluator接口)
2.Evaluator需要實現 init、iterate、terminatePartial、merge、terminate這幾個函數
init():類似於構造函數,用於UDAF的初始化
iterate():接收傳入的參數,並進行內部的輪轉,返回boolean
terminatePartial():無參數,其爲iterate函數輪轉結束後,返回輪轉數據,類似於hadoop的Combiner
merge():接收terminatePartial的返回結果,進行數據merge操作,其返回類型爲boolean
terminate():返回最終的聚集函數結果
開發一個功能同:
- Oracle的wm_concat()函數
- Mysql的group_concat()