HIVE User Guide 总结之四HIVE 的MAP/REDUCE、注意点
7.HIVE 的MAP/REDUCE
7.1 jion
????對于 JOIN 操作:
INSERT?OVERWRITE?TABLE?pv_users? SELECT?pv.pageid,?u.age?FROM?page_view?pv?JOIN?user?u?ON?(pv.userid?=?u.userid);???實現過程為:
Map:
以 JOIN ON 條件中的列作為 Key,如果有多個列,則 Key 是這些列的組合
以 JOIN 之后所關心的列作為 Value,當有多個列時,Value 是這些列的組合。在 Value 中還會包含表的 Tag 信息,用于標明此 Value 對應于哪個表。
按照 Key 進行排序。
Shuffle:
根據 Key 的值進行 Hash,并將 Key/Value 對按照 Hash 值推至不同對 Reduce 中。
Reduce:
Reducer 根據 Key 值進行 Join 操作,并且通過 Tag 來識別不同的表中的數據。
????具體實現過程如圖:
????
7.2 GROUP BY
SELECT?pageid,?age,?count(1)?FROM?pv_users?GROUP?BY?pageid,?age;7.3 DISTINCT
SELECT?age,?count(distinct?pageid)?FROM?pv_users?GROUP?BY?age;? 實現過程如圖:
8.使用HIVE注意點
8.1字符集
????Hadoop和Hive都是用UTF-8編碼的,所以,?所有中文必須是UTF-8編碼,?才能正常使用。
????備注:中文數據load到表里面,?如果字符集不同,很有可能全是亂碼需要做轉碼的,?但是hive本身沒有函數來做這個
????? 8.2 壓縮
??????????hive.exec.compress.output?這個參數,?默認是?false,但是很多時候貌似要單獨顯式設置一遍,否則會對結果做壓縮的,如果你的這個文件后面還要在hadoop下直接操作,?那么就不能壓縮了
????? 8.3 count(distinct)
???????? 當前的 Hive 不支持在一條查詢語句中有多 Distinct。如果要在 Hive 查詢語句中實現多Distinct,需要使用至少 n+1 條查詢語句(n為distinct的數目),前 n 條查詢分 別對 n 個列去重,最后一條查詢語句對 n 個去重之后的列做 Join 操作,得到最終結果。
??????8.4 Join
?????????只支持等值連接
??????8.5? DML操作
????? 只支持INSERT/LOAD操作,無UPDATE和DELTE
????? 8.6 HAVING
???????? 不支持HAVING操作。如果需要這個功能要嵌套一個子查詢用where限制
??????8.7 子查詢
?????????Hive不支持where子句中的子查詢
????? 8.8?Join中處理null值的語義區別
???????? SQL標準中,任何對null的操作(數值比較,字符串操作等)結果都為null。Hive對null值處理的邏輯和標準基本一致,除了Join時的特殊邏輯。
????這里的特殊邏輯指的是,Hive的Join中,作為Join key的字段比較,null=null是有意義的,且返回值為true。檢查以下查詢
select?u.uid,?count(u.uid)? from?t_weblog?l?join?t_user?u?on?(l.uid?=?u.uid)?group?by?u.uid;????????查詢中,t_weblog表中uid為空的記錄將和t_user表中uid為空的記錄做連接,即l.uid = u.uid=null成立。
如果需要與標準一致的語義,我們需要改寫查詢手動過濾null值的情況:
select?u.uid,?count(u.uid)? from?t_weblog?l?join?t_user?u?on?(l.uid?=?u.uid?and?l.uid?is?not?null?and?u.uid?is?not?null) group?by?u.uid;????????實踐中,這一語義區別也是經常導致數據傾斜的原因之一。
????? 8.9 分號字符
????????分號是SQL語句結束標記,在HiveQL中也是,但是在HiveQL中,對分號的識別沒有那么智慧,例如:
select?concat(cookie_id,concat(';',’zoo’))?from?c02_clickstat_fatdt1?limit?2;FAILED:?Parse?Error:?line?0:-1?cannot?recognize?input?'<EOF>'?in?function?specification 可以推斷,Hive解析語句的時候,只要遇到分號就認為語句結束,而無論是否用引號包含起來。????????解決的辦法是,使用分號的八進制的ASCII碼進行轉義,那么上述語句應寫成:
select?concat(cookie_id,concat('\073','zoo'))?from?c02_clickstat_fatdt1?limit?2;????????為什么是八進制ASCII碼?
????我嘗試用十六進制的ASCII碼,但Hive會將其視為字符串處理并未轉義,好像僅支持八進制,原因不詳。這個規則也適用于其他非SELECT語句,如CREATE TABLE中需要定義分隔符,那么對不可見字符做分隔符就需要用八進制的ASCII碼來轉義。
??????8.10 Insert
???????? 1. 新增數據
????????????根據語法Insert必須加“OVERWRITE”關鍵字,也就是說每一次插入都是一次重寫。那如何實現表中新增數據呢?
????? 假設Hive中有表xiaojun1,
hive>?DESCRIBE?xiaojun1; OK id?int value?int hive>?SELECT?*?FROM?xiaojun1; OK 3?4 1?2 2?3???????????? 現增加一條記錄:
hive>?INSERT?OVERWRITE?TABLE?xiaojun1? SELECT?id,?value?FROM?(SELECT?id,?value?FROM?xiaojun1?UNION?ALL?SELECT?4?AS?id,?5?AS?value?FROM?xiaojun1?limit?1 )?u; 結果是:? hive>SELECT?*?FROM?p1;? OK 3?4 4?5 2?3 1?2????????????其中的關鍵在于, 關鍵字UNION ALL的應用, 即將原有數據集和新增數據集進行結合, 然后重寫表
?????????2.插入次序
????????????INSERT OVERWRITE TABLE在插入數據時,是按照后面的SELECT語句中的字段順序插入的. 也就說, 當id 和value 的位置互換, 那么value將被寫入id, 同id被寫入value.
?????????3. 初始值
????????????INSERT OVERWRITE TABLE在插入數據時, 后面的字段的初始值應注意與表定義中的一致性. 例如, 當為一個STRING類型字段初始為NULL時:
NULL?AS?field_name?//?這可能會被提示定義類型為STRING,?但這里是void? CAST(NULL?AS?STRING)?AS?field_name?//?這樣是正確的???? 又如, 為一個BIGINT類型的字段初始為0時:
CAST(0?AS?BIGINT)?AS?field_namejiewei
轉載于:https://my.oschina.net/MrMichael/blog/307304
總結
以上是生活随笔為你收集整理的HIVE User Guide 总结之四HIVE 的MAP/REDUCE、注意点的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: RTKLIB学习总结(七)GNSS观测量
- 下一篇: python机器学习笔记:ID3决策树算