大資料技術之_09_Hive學習_複習與總結
一、知識梳理
1.1、背景表結構
在講解中我們需要貫串一個例子,所以需要設計一個情景,對應還要有一個表結構和填充資料。如下:有 3 個欄位,分別為 personId 標識某一個人,company 標識一家公司名稱,money 標識該公司每年盈利收入(單位:萬元人民幣)

建表並匯入資料:
create table company_info( personId string, company string, money float ) row format delimited fields terminated by "\t"; load data local inpath '/opt/module/datas/company_info.txt' into table company_info;
1.1.1、order by
hive 中的 order by 語句會對查詢結果做一次 全域性排序
,即,所有的 mapper 產生的結果都會交給一個 reducer 去處理,無論資料量大小,job 任務只會啟動一個 reducer,如果資料量巨大,則會耗費大量的時間。
尖叫提示
:如果在嚴格模式下,order by 需要指定 limit 資料條數,不然資料量巨大的情況下會造成崩潰無輸出結果。涉及屬性:set hive.mapred.mode=nonstrict/strict
例如:按照 money 排序的例子
select * from company_info order by money desc;
1.1.2、sort by
hive 中的 sort by 語句會對每一塊區域性資料進行 區域性排序
,即每一個 reducer 處理的資料都是有序的,但是不能保證全域性有序。
1.1.3、distribute by
hive 中的 distribute by 一般要和 sort by 一起使用,即將某一塊資料歸給(distribute by)某一個 reducer 處理,然後在指定的 reducer 中進行 sort by 排序。
尖叫提示
:distribute by 必須寫在 sort by 之前。
尖叫提示
:涉及屬性 mapreduce.job.reduces,hive.exec.reducers.bytes.per.reducer
例如:不同的人(personId)分為不同的組,每組按照 money 排序。
select * from company_info distribute by personId sort by personId asc, money desc;
1.1.4、cluster by
hive 中的 cluster by 在 distribute by 和 sort by 排序欄位一致
的情況下是等價的。同時,cluster by 指定的列只能是 降序
,即預設的 descend,而不能是 ascend。
例如:寫一個等價於 distribute by 與 sort by 的例子。
select * from company_info distribute by personId sort by personId desc; 等價於 select * from compnay_info cluster by personId;
1.2、行轉列、列轉行(UDAF 與 UDTF)
1.2.1、行轉列
1、相關函式說明
1)CONCAT(string A/col, string B/col, …):返回輸入字串連線後的結果,支援任意個輸入字串。
2)CONCAT_WS(separator, str1, str2,…):它是一個 特殊形式的CONCAT()
。第一個引數是剩餘引數間的分隔符。分隔符可以是與剩餘引數一樣的字串。如果分隔符是 NULL,返回值也將為 NULL。這個函式會跳過分隔符引數後的任何 NULL 和空字串。分隔符將被加到被連線的字串之間。
3)COLLECT_SET(col):函式只接受基本資料型別,它的主要作用是 將某欄位的值進行去重彙總,產生array型別欄位
。
2、資料準備
person_info.txt

3、需求
把星座和血型一樣的人歸類到一起。結果如下:
射手座,A大海|鳳姐 白羊座,A孫悟空|豬八戒 白羊座,B宋宋
分析過程:

4、建立本地person_info.txt,匯入資料
[atguigu@hadoop102 datas]$ vim person_info.txt 孫悟空白羊座 A 大海射手座 A 宋宋白羊座 B 豬八戒白羊座 A 鳳姐射手座 A
5、建立hive表並匯入資料
create table person_info( name string, constellation string, blood_type string ) row format delimited fields terminated by "\t"; load data local inpath '/opt/module/datas/person_info.txt' into table person_info;
6、按需求查詢資料
select concat_ws(",", constellation, blood_type) as c_b, name from person_info; t1 +--------+-------+--+ |c_b| name| +--------+-------+--+ | 白羊座,A| 孫悟空| | 射手座,A| 大海| | 白羊座,B| 宋宋| | 白羊座,A| 豬八戒| | 射手座,A| 鳳姐| +--------+-------+--+ -------------------- select t1.c_b, collect_set(t1.name) from (select concat_ws(",", constellation, blood_type) as c_b, name from person_info) t1 group by t1.c_b; +---------+----------------+--+ | t1.c_b|_c1| +---------+----------------+--+ | 射手座,A| ["大海","鳳姐"]| | 白羊座,A| ["孫悟空","豬八戒"]| | 白羊座,B| ["宋宋"]| +---------+----------------+--+ -------------------- select t1.c_b, concat_ws("|", collect_set(t1.name)) name from (select concat_ws(",", constellation, blood_type) as c_b, name from person_info) t1 group by t1.c_b; +---------+----------+--+ | t1.c_b|name| +---------+----------+--+ | 射手座,A| 大海|鳳姐| | 白羊座,A| 孫悟空|豬八戒| | 白羊座,B| 宋宋| +---------+----------+--+
1.2.2、列轉行
1、函式說明
EXPLODE(col):將hive一列中複雜的array或者map結構拆分成多行。
LATERAL VIEW
用法:LATERAL VIEW udtf(expression) tableAlias AS columnAlias
解釋:lateral view 用於和split,explode等UDTF函式一起使用,它能夠將一列資料拆成多行資料,在此基礎上可以對拆分後的資料進行聚合。
2、資料準備
movie_info.txt
moviecategory 《疑犯追蹤》懸疑,動作,科幻,劇情 《Lie to me》懸疑,警匪,動作,心理,劇情 《戰狼2》戰爭,動作,災難
3、需求
將電影分類中的陣列資料展開。結果如下:
《疑犯追蹤》懸疑 《疑犯追蹤》動作 《疑犯追蹤》科幻 《疑犯追蹤》劇情 《Lie to me》懸疑 《Lie to me》警匪 《Lie to me》動作 《Lie to me》心理 《Lie to me》劇情 《戰狼2》戰爭 《戰狼2》動作 《戰狼2》災難
4、建立本地movie.txt,匯入資料
[atguigu@hadoop102 datas]$ vim movie_info.txt 《疑犯追蹤》懸疑,動作,科幻,劇情 《Lie to me》懸疑,警匪,動作,心理,劇情 《戰狼2》戰爭,動作,災難
5、建立hive表並匯入資料
create table movie_info( movie string, category array<string> ) row format delimited fields terminated by "\t" -- 表中欄位與欄位之間的分割符是\t collection items terminated by ","; -- 集合欄位中的每個元素之間的分隔符是逗號 load data local inpath "/opt/module/datas/movie_info.txt" into table movie_info;
6、按需求查詢資料
select movie explode(category) from movie_info; 上面是錯誤的。假設能執行的話,得到的是笛卡爾積。 小結:像split,explode等UDTF函式,是不能跟原表的欄位直接進行查詢的,UDTF函式一定要和lateral view聯合在一塊用。 ----------------------------------------- select movie, category_name from movie_info lateral view explode(category) table_tmp as category_name; -- lateral view 對原始表的集合欄位進行了側寫,得到側寫表和側寫列(側寫欄位)。
1.3、建表時的陣列操作
fields terminated by:標識一張表中欄位與欄位之間的分隔符。
collection items terminated by:標識一個欄位(陣列欄位)中各個子元素(item)的分隔符。注意:若有兩個或兩個以上的陣列欄位,那麼他們的分隔符都得一樣。
1.4、orc 儲存
orc 即 Optimized Row Columnar (ORC) file,在 RCFile 的基礎上演化而來,可以提供一種高效的方法在 Hive 中儲存資料,提升了讀、寫、處理資料的效率。
1.5、Hive 分桶
為什麼要用Hive 分桶?
答:分割槽會產生新的檔案和目錄,在HDFS系統上NameNOde的壓力會增大。
Hive 可以將表或者表的分割槽進一步組織成桶,以達到:
1、資料取樣效率更高
2、資料處理效率更高
桶通過對指定列進行雜湊來實現,將一個列名下的資料切分為“一組桶”,每個桶都對應了一個該列名下的一個儲存檔案。
1.5.1、直接分桶
開始操作之前,需要將 hive.enforce.bucketing 屬性設定為 true,以標識 Hive 可以識別桶。
create table music( id int, name string, size float ) row format delimited fields terminated by "\t" clustered by (id) into 4 buckets;
該程式碼的意思是將 music 表按照 id 將資料分成了 4 個桶,插入資料時,會對應 4 個 reduce 操作,輸出 4 個檔案。
分桶演算法
:id.hashCode % 4(桶數)
Map集合key去重的原理和set集合去重原理
:先比較雜湊值(本質是比較地址值,hashCode()),再比較所對應的具體值(equals())。
set集合儲存資料的本質是使用 Map集合
來儲存的。
Map集合儲存資料的本質是使用 陣列
來儲存的。
陣列儲存資料的本質是使用 索引+值
來儲存的。
1.5.2、在分割槽中分桶
當資料量過大,需要龐大分割槽數量時,可以考慮桶,因為 分割槽數量太大的情況可能會導致檔案系統(HDFS)掛掉
,而且桶比分割槽有更高的查詢效率。資料最終落在哪一個桶裡,取決於 clustered by 的那個列的值的 hash 數與桶的個數求餘來決定。雖然有一定離散性,但不能保證每個桶中的資料量是一樣的。
create table music2( id int, name string, size float ) partitioned by(date string) clustered by(id) sorted by(size) into 4 bucket row format delimited fields terminated by "\t"; load data local inpath '/opt/module/datas/music2.txt' into table music2 partition(date='2017-08-30');
二、總結
2.1 啟動/停止hadoop叢集、zookeeper叢集、歷史伺服器
[atguigu@hadoop102 hadoop-2.7.2]$ sbin/start-dfs.sh -- 啟動dfs叢集 [atguigu@hadoop103 hadoop-2.7.2]$ sbin/start-yarn.sh -- 啟動yarn叢集 [atguigu@hadoop102 ~]$ zkstart.sh -- 啟動zookeeper叢集 [atguigu@hadoop102 hadoop-2.7.2]$ sbin/mr-jobhistory-daemon.sh start historyserver -- 啟動歷史伺服器 [atguigu@hadoop102 hadoop-2.7.2]$ sbin/stop-dfs.sh -- 停止dfs叢集 [atguigu@hadoop103 hadoop-2.7.2]$ sbin/stop-yarn.sh -- 停止yarn叢集 [atguigu@hadoop102 ~]$ zkstop.sh -- 停止zookeeper叢集 [atguigu@hadoop102 hadoop-2.7.2]$ sbin/mr-jobhistory-daemon.sh stop historyserver -- 停止歷史伺服器
2.2 訪問hive的兩種方式
方式一: [atguigu@hadoop102 hive]$ bin/hive -- 啟動hive 方式二: [atguigu@hadoop102 hive]$ bin/hiveserver2 [atguigu@hadoop102 hive]$ bin/beeline(在新的視窗中輸入) Beeline version 1.2.1 by Apache Hive beeline> !connect jdbc:hive2://hadoop102:10000(回車) Connecting to jdbc:hive2://hadoop102:10000 Enter username for jdbc:hive2://hadoop102:10000: atguigu(回車) Enter password for jdbc:hive2://hadoop102:10000: (直接回車) Connected to: Apache Hive (version 1.2.1) Driver: Hive JDBC (version 1.2.1) Transaction isolation: TRANSACTION_REPEATABLE_READ 0: jdbc:hive2://hadoop102:10000> show databases; +----------------+--+ | database_name| +----------------+--+ | default| | hive_db2| +----------------+--+
2.3 CentOS6x與Cenos7x命令的區別
CentOS6x [atguigu@hadoop102 ~]$ sudo service mysqld restart CentOS7x [atguigu@hadoop102 ~]$ sudo systemctl restart mysqld.service
2.4 大資料開發中重用的兩種資料格式
xxx.tsv 檔案中的欄位是以\t來分割的。
xxx.csv 檔案中的欄位是以逗號(,)來分割的。(comma:逗號)
2.5 UDF、UDAF、UDTF
collect_set(clo) 將多行資料聚合成一列資料,UDAF函式
concat_ws(separator, str1, str2,…) 聚合函式,UDAF函式
split((col),explode(col) 將一列資料拆成多行資料,UDTF函式
2.6 小知識總結
分桶演算法
:id.hashCode % 4(桶數)
Map集合key去重的原理和set集合去重原理
:先比較雜湊值(本質是比較地址值,hashCode()),再比較所對應的具體值(equals())。
set集合儲存資料的本質是使用 Map集合
來儲存的。
Map集合儲存資料的本質是使用 陣列
來儲存的。
陣列儲存資料的本質是使用 索引+值
來儲存的。