Hive体系结构(四)注意事项与扩展特性
Hive體系結構(一)架構與基本組成
Hive體系結構(二)Hive的執行原理、與關系型數據庫的比較
Hive體系結構(三)元數據庫與基本操作
Hive體系結構(四)注意事項與擴展特性
1. 使用HIVE注意點
Hadoop和Hive都是用UTF-8編碼的,所以, 所有中文必須是UTF-8編碼, 才能正常使用。
備注:中文數據load到表里面,,如果字符集不同,很有可能全是亂碼需要做轉碼的,但是hive本身沒有函數來做這個。
hive.exec.compress.output 這個參數,默認是false,但是很多時候貌似要單獨顯式設置一遍,否則會對結果做壓縮的,如果你的這個文件后面還要在hadoop下直接操作,那么就不能壓縮了。
當前的Hive不支持在一條查詢語句中有多Distinct。如果要在Hive查詢語句中實現多Distinct,需要使用至少n+1條查詢語句(n為distinct的數目),前n條查詢分別對n個列去重,最后一條查詢語句對n個去重之后的列做Join操作,得到最終結果。
只支持等值連接
只支持INSERT/LOAD操作,無UPDATE和DELTE
不支持HAVING操作。如果需要這個功能要嵌套一個子查詢用where限制
Hive不支持where子句中的子查詢
SQL標準中,任何對null的操作(數值比較,字符串操作等)結果都為null。Hive對null值處理的邏輯和標準基本一致,除了Join時的特殊邏輯。這里的特殊邏輯指的是,Hive的Join中,作為Join key的字段比較,null=null是有意義的,且返回值為true。
分號是SQL語句結束標記,在HiveQL中也是,但是在HiveQL中,對分號的識別沒有那么智慧,例如:
可以推斷,Hive解析語句的時候,只要遇到分號就認為語句結束,而無論是否用引號包含起來。
解決的辦法是,使用分號的八進制的ASCII碼進行轉義,那么上述語句應寫成:
為什么是八進制ASCII碼?我嘗試用十六進制的ASCII碼,但Hive會將其視為字符串處理并未轉義,好像僅支持八進制,原因不詳。這個規則也適用于其他非SELECT語句,如CREATE TABLE中需要定義分隔符,那么對不可見字符做分隔符就需要用八進制的ASCII碼來轉義。
10. Insert
根據語法Insert必須加“OVERWRITE”關鍵字,也就是說每一次插入都是一次重寫。
2. Hive的擴展特性
Hive 是一個很開放的系統,很多內容都支持用戶定制,包括:
* 文件格式:Text File,Sequence File
* 內存中的數據格式: Java Integer/String, Hadoop IntWritable/Text
* 用戶提供的map/reduce腳本:不管什么語言,利用stdin/stdout傳輸數據
* 用戶自定義函數:Substr, Trim, 1 – 1
* 用戶自定義聚合函數:Sum, Average…… n – 1
2.1 數據文件格式
| Data type | Text Only | Text/Binary |
| Internal Storage Order | Row-based | Row-based |
| Compression | File Based | Block Based |
| Splitable | YES | YES |
| Splitable After Compression | No | YES |
例如使用文件文件格式存儲創建的表:
CREATE TABLE mylog ( user_id BIGINT, page_url STRING, unix_time INT) STORED AS TEXTFILE;當用戶的數據文件格式不能被當前Hive所識別的時候,可以自定義文件格式??梢詤⒖糲ontrib/src/java/org/apache/hadoop/hive/contrib/fileformat/base64中的例子。寫完自定義的格式后,在創建表的時候指定相應的文件格式就可以:
CREATE TABLE base64_test(col1 STRING, col2 STRING) STORED AS INPUTFORMAT 'org.apache.hadoop.hive.contrib.fileformat.base64.Base64TextInputFormat' OUTPUTFORMAT 'org.apache.hadoop.hive.contrib.fileformat.base64.Base64TextOutputFormat';2.2 SerDe
SerDe是Serialize/Deserilize的簡稱,目的是用于序列化和反序列化。
序列化的格式包括:分隔符(tab、逗號、CTRL-A)、Thrift 協議。
反序列化(內存內):Java Integer/String/ArrayList/HashMap、Hadoop Writable類、用戶自定義類。
其中,LazyObject只有在訪問到列的時候才進行反序列化。 BinarySortable保留了排序的二進制格式。
當存在以下情況時,可以考慮增加新的SerDe:
* 用戶的數據有特殊的序列化格式,當前的Hive不支持,而用戶又不想在將數據加載至Hive前轉換數據格式。
* 用戶有更有效的序列化磁盤數據的方法。
用戶如果想為Text數據增加自定義Serde,可以參照contrib/src/java/org/apache/hadoop/hive/contrib/serde2/RegexSerDe.java中的例子。RegexSerDe利用用戶提供的正則表倒是來反序列化數據,例如:
CREATE TABLE apache_log( host STRING, identity STRING, user STRING, time STRING, request STRING, status STRING, size STRING, referer STRING, agent STRING) ROW FORMAT SERDE 'org.apache.hadoop.hive.contrib.serde2.RegexSerDe' WITH SERDEPROPERTIES ( "input.regex" = "([^ ]*) ([^ ]*) ([^ ]*) (-|\\[[^\\]]*\\]) ([^ \"]*|\"[^\"]*\") (-|[0-9]*) (-|[0-9]*)(?: ([^ \"]*|\"[^\"]*\") ([^ \"]*|\"[^\"]*\"))?", "output.format.string" = "%1$s %2$s %3$s %4$s %5$s %6$s %7$s %8$s %9$s";) STORED AS TEXTFILE;用戶如果想為Binary數據增加自定義的SerDe,可以參考例子serde/src/java/org/apache/hadoop/hive/serde2/binarysortable,例如:
CREATE TABLE mythrift_table ROW FORMAT SERDE 'org.apache.hadoop.hive.contrib.serde2.thrift.ThriftSerDe' WITH SERDEPROPERTIES ( "serialization.class" = "com.facebook.serde.tprofiles.full", "serialization.format" = "com.facebook.thrift.protocol.TBinaryProtocol";);2.3 Map/Reduce腳本(Transform)
用戶可以自定義Hive使用的Map/Reduce腳本,比如:
FROM ( SELECT TRANSFORM(user_id, page_url, unix_time) USING 'page_url_to_id.py' AS (user_id, page_id, unix_time) FROM mylog DISTRIBUTE BY user_id SORT BY user_id, unix_time) mylog2 SELECT TRANSFORM(user_id, page_id, unix_time) USING 'my_python_session_cutter.py' AS (user_id, session_info);Map/Reduce腳本通過stdin/stdout進行數據的讀寫,調試信息輸出到stderr。
2.4 UDF(User-Defined-Function)
用戶可以自定義函數對數據進行處理,例如:
add jar build/ql/test/test-udfs.jar; CREATE TEMPORARY FUNCTION testlength AS 'org.apache.hadoop.hive.ql.udf.UDFTestLength'; SELECT testlength(src.value) FROM src; DROP TEMPORARY FUNCTION testlength;UDFTestLength.java為:
package org.apache.hadoop.hive.ql.udf;public class UDFTestLength extends UDF {public Integer evaluate(String s) {if (s == null) {return null;}return s.length();} }UDF 具有以下特性:
* 用java寫UDF很容易。
* Hadoop的Writables/Text 具有較高性能。
* UDF可以被重載。
* Hive支持隱式類型轉換。
* UDF支持變長的參數。
* genericUDF 提供了較好的性能(避免了反射)。
2.5 UDAF(User-Defined Aggregation Funcation)
例子:
SELECT page_url, count(1), count(DISTINCT user_id) FROM mylog;UDAFCount.java代碼如下:
public class UDAFCount extends UDAF {public static class Evaluator implements UDAFEvaluator {private int mCount;public void init() {mcount = 0;}public boolean iterate(Object o) {if (o!=null)mCount++;return true;}public Integer terminatePartial() {return mCount;}public boolean merge(Integer o) {mCount += o;return true;}public Integer terminate() {return mCount;} }總結
以上是生活随笔為你收集整理的Hive体系结构(四)注意事项与扩展特性的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Hive体系结构(三)元数据库与基本操作
- 下一篇: HDFS High Availabili