Hive使用入门
Hive簡(jiǎn)介
hive是基于Hadoop的一個(gè)數(shù)據(jù)倉(cāng)庫(kù)工具,可以將結(jié)構(gòu)化的數(shù)據(jù)文件映射為一張數(shù)據(jù)庫(kù)表,并提供簡(jiǎn)單的sql查詢功能,可以將sql語(yǔ)句轉(zhuǎn)換為MapReduce任務(wù)進(jìn)行運(yùn)行。 其優(yōu)點(diǎn)是學(xué)習(xí)成本低,可以通過(guò)類SQL語(yǔ)句快速實(shí)現(xiàn)簡(jiǎn)單的MapReduce統(tǒng)計(jì),不必開(kāi)發(fā)專門的MapReduce應(yīng)用,十分適合數(shù)據(jù)倉(cāng)庫(kù)的統(tǒng)計(jì)分析。
建立Hive表
hive中創(chuàng)建表時(shí),默認(rèn)情況下hive負(fù)責(zé)管理數(shù)據(jù),這就是所謂的“托管表”。建立托管表的語(yǔ)法比較簡(jiǎn)單,和寫SQL建表也比較類似:
DROP TABLE example_table; CREATE TABLE if not exists example_table(example_id STRING, example_name STRING ) row format delimited fields terminated by ',';
需要注意的是,建立字段的定義,以及row的delimeter,這里指定為”,”。
托管表建立完成后,表中并無(wú)數(shù)據(jù),這就需要我們向表中插入一些數(shù)據(jù)。但Hive中并不可以通過(guò)insert一條數(shù)據(jù)的方式向表中插入數(shù)據(jù),可以通過(guò)下面的方式從本地文件中加載(當(dāng)然也可以從HDFS中加載,語(yǔ)法稍微不同):
LOAD DATA LOCAL INPATH 'LocalFile' OVERWRITE INTO TABLE region_table;
由于在第一步中我們已經(jīng)設(shè)定行分隔符為’,’,這里的LocalFile的每一行都要由,進(jìn)行分隔,并在加載完成后,對(duì)應(yīng)到定義的字段中去。
但在我們的實(shí)際應(yīng)用場(chǎng)景下,Hive中使用的數(shù)據(jù)大部分都是從外部文件中得到的,這時(shí)候就需要?jiǎng)?chuàng)建“外部表”。
drop table task_table; create external table if not exists task_table ( doc string ) stored as inputformat 'Hive進(jìn)行的InputFormat轉(zhuǎn)換' outputformat 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat' location '/數(shù)據(jù)所在的HDFS文件夾/';
使用external關(guān)鍵字之后,Hive就知道數(shù)據(jù)并不是托管的,不會(huì)將數(shù)據(jù)移到自己的數(shù)據(jù)倉(cāng)庫(kù)目錄中;而且在drop外部表時(shí),也不會(huì)碰數(shù)據(jù),只會(huì)刪除hive中的元數(shù)據(jù)。
InputFormat
和Hadoop中的InputFormat類似,我們?cè)诙x外部表時(shí),需要指定特定的InputFormat以將HDFS上的文件按行映射到對(duì)應(yīng)的數(shù)據(jù)上去。但是,我們?cè)贑REATE外部表語(yǔ)句中定義的InputFormat與Hadoop中Map使用的InputFormat有所不同,外部表中的定義的InputFormat并不能決定map分片數(shù)量。
在hive中運(yùn)行“select * from example_table”時(shí)直接返回當(dāng)前所有值,并不會(huì)啟動(dòng)mapreduce任務(wù),而當(dāng)構(gòu)建一些復(fù)雜的特殊的HQL語(yǔ)句時(shí),就會(huì)啟動(dòng)一個(gè)mapreduce任務(wù)來(lái)進(jìn)行處理。
hive中運(yùn)行參數(shù)的設(shè)置可以通過(guò)hive命令中的“--hive-conf 參數(shù)名=參數(shù)值”來(lái)定義,在hive啟動(dòng)的mapreduce任務(wù)中,使用的默認(rèn)是org.apache.hadoop.hive.ql.io.CombineHiveInputFormat類,與table中定義的InputFormat根本無(wú)關(guān),了解hadoop的應(yīng)該知道,Combine表示可能會(huì)合并多個(gè)小文件一起處理,與我們當(dāng)前需求并不符合。而如果需要設(shè)置每個(gè)文件只能由一個(gè)map任務(wù)來(lái)處理時(shí),原來(lái)的繼承FileInputFormat并重寫isSplittable方法并不起作用,拋出異常。這是因?yàn)镠ive中啟動(dòng)的mapreduce任務(wù)的InputFormat必須是org.apache.hadoop.hive.ql.io.HiveInputFormat的子類,可以通過(guò)設(shè)置mapred.input.format.class=org.apache.hadoop.hive.ql.io.HiveInputFormat,并將參數(shù)mapreduce.input.fileinputformat.split.minsize設(shè)置(單位是字節(jié))的非常大來(lái)達(dá)到目的。
也可以在hive配置文件中進(jìn)行整體的調(diào)整:
<property>
<name>mapreduce.input.fileinputformat.split.minsize</name>
<value>1099511627776</value>
</property>
<property>
<name>hive.input.format</name>
<value>org.apache.hadoop.hive.ql.io.HiveInputFormat</value>
</property>
UDF函數(shù)
Hive中有很多的內(nèi)置函數(shù),如果可以通過(guò)內(nèi)置函數(shù)來(lái)解決,就不需要編寫UDF來(lái)完成任務(wù)。
可以通過(guò)下面的命令來(lái)顯示出hive中的所有內(nèi)置函數(shù):
hive -e "show functions";
比如可以使用from_unixtime,cast, hour三個(gè)函數(shù)的組合來(lái)完成將時(shí)間轉(zhuǎn)換成小時(shí)的工作:
hour(from_unixtime(cast(raw['ti'] as bigint),'yyyy-MM-dd HH:mm:ss'))
如何在hive中自定義UDF(User Define Function)?這里說(shuō)明一下如何在java中定義UDF。
首先,需要繼承類:org.apache.hadoop.hive.ql.exec.UDF,并寫一個(gè)名稱為evaluate的函數(shù),由于Hive使用的是反射的方式來(lái)進(jìn)行調(diào)用的,并不強(qiáng)調(diào)參數(shù)以及返回值,可以隨便寫,在使用時(shí)注意就可以了(甚至可以在UDF函數(shù)中重載多個(gè)evaludate方法)。
編寫完成后,需要在HQL腳本中使用下面的方式來(lái)進(jìn)行調(diào)用:
add jar “對(duì)應(yīng)的jar包路徑” create temporary function function_name as 'UDF類名稱';
之后,就可以在sql中使用function_name進(jìn)行操作,注意其輸入?yún)?shù)以及返回值。
HQL語(yǔ)句
hive中可以執(zhí)行HQL語(yǔ)句,其基本格式與SQL語(yǔ)句非常類似。可以通過(guò)hive shell的方式執(zhí)行,也可以通過(guò)hive –e “hql語(yǔ)句”或hive –f “hql文件”的方式執(zhí)行。
示例:
select example_udf_function(doc) raw from example_table;
此外,HQL語(yǔ)句還支持嵌套。這部分只是個(gè)入門教程,因此,后續(xù)深入研究。
總結(jié)
- 上一篇: 计算机视觉课_计算机视觉教程—第4课
- 下一篇: 用camelot读取表格_如何使用Cam