鎖屏面試題百日百刷-Hive篇(九)
? ? 鎖屏面試題百日百刷,每個工作日堅(jiān)持更新面試題。鎖屏面試題app、小程序現(xiàn)已上線,官網(wǎng)地址:https://www.demosoftware.cn。已收錄了每日更新的面試題的所有內(nèi)容,還包含特色的解鎖屏幕復(fù)習(xí)面試題、每日編程題目郵件推送等功能。讓你在面試中先人一步!接下來的是今日的面試題:
1.Hive中使用什么代替in查詢?
在Hive 0.13版本之前,通過left outer join實(shí)現(xiàn)SQL中的in查詢,0.13版本之后,Hive已經(jīng)支持in查詢。
2.所有的Hive任務(wù)都會有MapReduce的執(zhí)行嗎?
不是,從Hive0.10.0版本開始,對于簡單的不需要聚合的類似SELECT <col> from <table> LIMIT n語句,不需要起MapReduce job,直接通過Fetch task獲取數(shù)據(jù)。
3.Hive的函數(shù):UDF、UDAF、UDTF的區(qū)別?
UDF: 單行進(jìn)入,單行輸出
UDAF: 多行進(jìn)入,單行輸出
UDTF: 單行輸入,多行輸出
(1)UDF(User-Defined-Function)
一進(jìn)一出
(2)UDAF(User-Defined Aggregation Function)
聚集函數(shù),多進(jìn)一出
類似于:count/max/min
(3)UDTF(User-Defined Table-Generating Functions)
一進(jìn)多出
如lateral view explore()
4.Hive自定義UDF函數(shù)的流程?
1)寫一個類繼承(org.apache.hadoop.hive.ql.)UDF類;
2)覆蓋方法evaluate();
3)打JAR包;
4)通過hive命令將JAR添加到Hive的類路徑:
hive> add jar /home/ubuntu/ToDate.jar;
5)注冊函數(shù):
hive> create temporary function xxx as 'XXX';
6)使用函數(shù);
7)[可選] drop臨時函數(shù);
5.拉鏈表是什么,怎么使用?
拉鏈表就是之前我們講過的SCD2,它的優(yōu)點(diǎn)是即滿足了反應(yīng)數(shù)據(jù)的歷史狀態(tài),又能在最大程度上節(jié)省存儲。
拉鏈表的實(shí)現(xiàn)需要在原始字段基礎(chǔ)上增加兩個新字段:
l start_time(表示該條記錄的生命周期開始時間——周期快照時的狀態(tài))
l end_time(該條記錄的生命周期結(jié)束時間)
拉鏈表實(shí)現(xiàn)步驟:
1. 建立增量數(shù)據(jù)臨時表update;
2. 抽取昨日增量數(shù)據(jù)到update表;
3. 建立臨時合并表tmp;
4. 合并昨日增量數(shù)據(jù)與歷史數(shù)據(jù),將重復(fù)的舊數(shù)據(jù)end_time更新為昨日,也就是從今天起不再生效;新數(shù)據(jù)end_time改為’9999-12-31’,也就是當(dāng)前有效;合并后的數(shù)據(jù)寫入到tmp表;
5. 將臨時表的數(shù)據(jù),覆蓋到拉鏈表中;
6. 下次抽取需要重建update表和tmp表。
查詢拉鏈表數(shù)據(jù)時,可以通過start_time和end_time查詢出快照數(shù)據(jù)。
6.Hive為什么要分桶?
(1)獲得更高的查詢處理效率
在分區(qū)數(shù)量過于龐大以至于可能導(dǎo)致文件系統(tǒng)崩潰時,或數(shù)據(jù)集找不到合理的分區(qū)字段時,我們就需要使用分桶來解決問題了。
分區(qū)中的數(shù)據(jù)可以被進(jìn)一步拆分成桶,不同于分區(qū)對列直接進(jìn)行拆分,桶往往使用列的哈希值對數(shù)據(jù)打散,并分發(fā)到各個不同的桶中從而完成數(shù)據(jù)的分桶過程。
注意,hive使用對分桶所用的值進(jìn)行hash,并用hash結(jié)果除以桶的個數(shù)做取余運(yùn)算的方式來分桶,保證了每個桶中都有數(shù)據(jù),但每個桶中的數(shù)據(jù)條數(shù)不一定相等。
如果另外一個表也按照同樣的規(guī)則分成了一個個小文件。兩個表join的時候,就不必要掃描整個表,只需要匹配相同分桶的數(shù)據(jù)即可,從而提升效率。
在數(shù)據(jù)量足夠大的情況下,分桶比分區(qū)有更高的查詢效率。
(2)數(shù)據(jù)采樣
在真實(shí)的大數(shù)據(jù)分析過程中,由于數(shù)據(jù)量較大,開發(fā)和自測的過程比較慢,嚴(yán)重影響系統(tǒng)的開發(fā)進(jìn)度。此時就可以使用分桶來進(jìn)行數(shù)據(jù)采樣。采樣使用的是一個具有代表性的查詢結(jié)果而不是全部結(jié)果,通過對采樣數(shù)據(jù)的分析,來達(dá)到快速開發(fā)和自測的目的,節(jié)省大量的研發(fā)成本。
(3)分桶和分區(qū)的區(qū)別
1. 分桶和分區(qū)兩者不干擾,可以把分區(qū)表進(jìn)一步分桶;
2. 分桶對數(shù)據(jù)的處理比分區(qū)更加細(xì)粒度化:分區(qū)針對的是數(shù)據(jù)的存儲路徑;分桶針對的
是數(shù)據(jù)文件;
3. 分桶是按照列的哈希函數(shù)進(jìn)行分割的,相對比較平均;而分區(qū)是按照列的值來進(jìn)行分
割的,容易造成數(shù)據(jù)傾斜。
(4) 文本數(shù)據(jù)處理
注意:對于分桶表,不能使用load data的方式進(jìn)行數(shù)據(jù)插入操作,因?yàn)閘oad data導(dǎo)入的數(shù)據(jù)不會有分桶結(jié)構(gòu)。
如何避免針對桶表使用load data插入數(shù)據(jù)的誤操作呢?
--限制對桶表進(jìn)行l(wèi)oad操作
set hive.strict.checks.bucketing = true;
也可以在CM的hive配置項(xiàng)中修改此配置,當(dāng)針對桶表執(zhí)行l(wèi)oad data操作時會報(bào)錯。
那么對于文本數(shù)據(jù)如何處理呢?
(1. 先創(chuàng)建臨時表,通過load data將txt文本導(dǎo)入臨時表。
--創(chuàng)建臨時表
create table temp_buck(id int,?name string) row format delimited fields terminated by '\t'; --導(dǎo)入數(shù)據(jù)
load data local inpath '/tools/test_buck.txt' into table temp_buck;
(2. 使用insert select語句間接的把數(shù)據(jù)從臨時表導(dǎo)入到分桶表。
--啟用桶表
set hive.enforce.bucketing=true; --限制對桶表進(jìn)行l(wèi)oad操作
set hive.strict.checks.bucketing = true; --insert select
insert into table test_buck select id, name from temp_buck; --分桶成功