Hive使用必知必會系列

来源:https://www.cnblogs.com/importbigdata/archive/2019/04/24/10765543.html
-Advertisement-
Play Games

一、Hive的幾種數據模型 內部表 (Table 將數據保存到Hive 自己的數據倉庫目錄中:/usr/hive/warehouse) 外部表 (External Table 相對於內部表,數據不在自己的數據倉庫中,只保存數據的元信息) 分區表 (Partition Table將數據按照設定的條件分 ...


一、Hive的幾種數據模型

  • 內部表 (Table 將數據保存到Hive 自己的數據倉庫目錄中:/usr/hive/warehouse)

  • 外部表 (External Table 相對於內部表,數據不在自己的數據倉庫中,只保存數據的元信息)

  • 分區表 (Partition Table將數據按照設定的條件分開存儲,提高查詢效率,分區----->  目錄)

  • 桶表 (Bucket Table本質上也是一種分區表,類似 hash 分區   桶 ----> 文件)

  • 視圖表 (視圖表是一個虛表,不存儲數據,用來簡化複雜的查詢)

註意:內部表刪除表後數據也會刪除,外部表數據刪除後不會從hdfs中刪除

 

1. 內部表/管理表

 

  • 每一個Table在Hive中都有一個相應的目錄存儲數據

  • 所有的Table數據都存儲在該目錄

# 創建表
create table if not exists aiops.appinfo (
appname string,
level string,
leader string,
appline string,
dep string,
ips array<string>)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ' '
COLLECTION ITEMS TERMINATED BY ',';

# 自定義文件和記錄格式
## 使用create table創建表,最後使用stored as sequencefile保存成sequence格式[預設是text格式]

# 資料庫授權
hive> grant create on database dbname to user hadoop;

# 導入數據(本地導入和hdfs導入)
hive> load data inpath 'hdfs://hdfs-name/sure.csv' overwrite into table aiops.appinfo;
load data local inpath '/home/hdfs/online_state1' overwrite into table online_state PARTITION (end_dt='99991231');

# 查看表結構
hive> describe extended bgops;
hive> describe bgops;

# 修改列名
## 這個命令可以修改表的列名,數據類型,列註釋和列所在的位置順序,FIRST將列放在第一列,AFTER col_name將列放在col_name後面一列
hive> ALTER TABLE aiops.appinfo CHANGE hostnum ipnum int comment 'some 註釋' AFTER col3;

# 修改表結構
ALTER TABLE aiops.appinfo replace columns (appname string,level string,leader string,appline string,dep string,ips array<string>);
ALTER TABLE appinfo replace columns (appname string,appline string,level string,leader string,dep string,idcnum int,idcs array<string>,hostnum int,ips array<string>);
## 增加表的列欄位(預設增加到最後一列,可以使用change column 來調整位置)
hive> alter table appinfo add columns (appclass string comment 'app_perf_class');

# 導出表查詢結果(會將結果導出到testoutput目錄下)
hive> insert overwrite local directory './testoutput'
> row format delimited fields terminated by "\t"
> select ip,appname,leader from appinfo LATERAL VIEW explode(ips) tmpappinfo AS ip;

外部表的使用場景

  • 原始日誌文件或同時被多個部門同時操作的數據集,需要使用外部表

  • 如果不小心將meta data刪除了,HDFS上的數據還在,可以恢復,增加了數據的安全性

註意:使用insert插入數據時會產生臨時表,重新連接後會表會小時,因此大批量插入數據時不建議用insert
tips1:在hdfs的hive路徑下以.db結尾的其實都是實際的資料庫
tips2:預設的default資料庫就在hive的家目錄

 

3. 分區表

註意:分區表通常分為靜態分區表和動態分區表,前者需要導入數據時靜態指定分區,後者可以直接根據導入數據進行分區。分區的好處是可以讓數據按照區域進行分類,避免了查詢時的全表掃描。

# 創建外部分區表,指定靜態分區為dt
CREATE EXTERNAL TABLE if not exists aiops.tmpOnline(ip string,
status string,
....
)
PARTITIONED BY (
dt string);

# 導入數據到靜態分區表中(需要註意的是數據中沒有dt欄位)
load data local inpath '/home/hdfs/tmpOnline' overwrite into table aiops.tmpOnline PARTITION (dt='99991231');

# 動態分區表的使用(動態分區和靜態分區表的創建時沒有區別的)
# 註意:hive預設沒有開啟動態分區,需要進行參數修改
# 使用動態分區的記錄中,必須在指定位置包含動態分區的欄位才能被動態分區表識別
hive>set hive.exec.dynamic.partition.mode=nonstrict;
hive>
insert
overwrite
table aiops.tmpOnline
partition(dt)
select
ip,appname,....,from_unixtime(unix_timestamp(),'yyyyMMdd') as dt from table;

# 手動添加分區
alter table tablename add partition (dt='20181009');
# 刪除分區,數據也會刪除(所以一般會使用外部分區表?)
## 註意:如果數據有變動,是無法將數據load到同一個時間分區的記錄的
alter table tablename drop partition (dt='20181009');
# 查詢分區表沒有加分區過濾,會禁止提交這個任務(strict方式每次查詢必須制定分區)
set hive.mapred.mode = strict|nostrict;

註意:在外部分區表中,如果將表刪除了,重建表後只需要將分區載入進來即可恢復歷史相關分區的數據。

多重分區的使用

# 創建多重分區表
create table log_m (
id int,
name string,
age int
)
partitioned by (year string,month string,day string)
row format delimited
fields terminated by '|'
collection items terminated by ','
map keys terminated by ':'
lines terminated by '\n';

# 插入數據
insert into table log_m partition (year='2018',month='10',day='10') values(1,'biaoge',24);
insert into table log_m partition (year='2018',month='10',day='09') values(2,'bgbiao',25);
hive> show partitions log_m;
OK
year=2018/month=10/day=09
year=2018/month=10/day=10
Time taken: 0.055 seconds, Fetched: 2 row(s)
hive>

# 多重動態分區
# 好像動態分區表不能直接load data
hive> insert into table log_m partition(year,month,day) values(3,'xuxuebiao',28,'2016','09','10');
hive> show partitions log_m;
OK
year=2016/month=09/day=10
year=2018/month=10/day=09
year=2018/month=10/day=10

# 查詢分區數據
hive> select * from log_m where year = '2018';
OK
2 bgbiao 25 2018 10 09
1 biaoge 24 2018 10 10
2 bgbiao 25 2018 10 10

 

二、Hive的複雜數據類型的使用

 

註意:Hive之所以能在大數據領域比較受歡迎,很大一部分原因在於相比其他SQL類存儲系統支持更加複雜的數據類型

  • map: (key1, value1, key2, value2, ...) 一些列的k/v對 map<int,string...>

  • struct: (var1,var2,var3...) 不同類型的值的組合 struct<abc:string,def:int...>

  • array: (var1,var2,var3...) 一種類型的值的組合 array<string...>

  • uniontype: (string,map<>,struct<>,array<>)

註意:在創建hive表時可根據需要導入的數據進行類型識別並創建適合的數據類型
hive數據類型數據識別標識:

欄位分割標識含義
FIELDS TERMINATED BY 表示欄位與欄位之間的分隔符
COLLECTION ITEMS TERMINATED BY 表示一個欄位中各個item之間的分隔符[可用於array和struct類型]
MAP KEYS TERMINATED BY 表示map類型中的key/value的分隔符[可用於map類型]
# 創建表
create table union_testnew(
foo uniontype<int, double, string, array<string>, map<string, string>>
)
row format delimited
collection items terminated by ','
map keys terminated by ':'
lines terminated by '\n'
stored as textfile;

# 數據準備
[root@master wadeyu]# vim union_test.log
1 0,1
2 1,3.0
3 2,world
4 3,wade:tom:polly
5 4,k1^Dv1:k2^Dv2

# 導入數據
hive (badou)> load data local inpath './union_test.log' overwrite into table union_testnew;

# 查詢數據
hive (badou)> select * from union_testnew;
OK
union_testnew.foo
{0:1}
{1:3.0}
{2:"world"}
{3:["wade","tom","polly"]}
{4:{"k1":"v1","k2":"v2"}}
Time taken: 0.225 seconds, Fetched: 5 row(s)

1. array類型的使用

1.1 array類型的基本使用

類型結構: array<struct> 例如:array<string>,array<int>
數據表示: 例如:[string1,string2],[int1,int2]

# 原始文件
bmpjob P2 bgops 服務研發組 10.0.0.212,10.0.0.225,10.0.0.243,10.0.55.31

# 創建資料庫
hive> create table appinfo
> (
> appname string,
> level string,
> leader string,
> dep string,
> ips array<string>)
> ROW FORMAT DELIMITED
> FIELDS TERMINATED BY ' '
> COLLECTION ITEMS TERMINATED BY ',';

# 載入數據到hive
hive> load data inpath 'hdfs://hdfs-name/aiops/wander/appinfo.txt' overwrite into table appinfo;
Loading data to table test.appinfo
Table test.appinfo stats: [numFiles=1, numRows=0, totalSize=32568, rawDataSize=0]
OK

# 查詢相關數據
hive> select * from appinfo limit 1;
OK
bmpjob P2 bgops 服務研發組 ["10.0.0.212","10.0.0.225","10.0.0.243","10.0.55.31"]

hive> select appname,leader,ips[0] from appinfo limit 1;
OK
bmpjob bgops 10.0.0.212

1.2 array<struct>類型數據轉換處理

背景:
使用array結構時,一個欄位中通常會有多個值,這個時候通常情況下是需要對某個值進行過濾的,一般情況下會使用lateral view結合UDTF(User-Defined Table-Generating Functions)進行過濾。而UDTF為瞭解決一行輸出多行的需求,典型的就是explode()函數。

lateral view語法結構

 

lateralView: LATERAL VIEW udtf(expression) tableAlias AS columnAlias (',' columnAlias)

array<struct>轉字元串

# 借用split函數將array<string>結構內容轉換為以","分割的字元串
select split(array<string>,',') from tablename

hive使用explode()函數進行行轉列
語法:lateral view explode(col3) col3 as name

  • explode(ARRAY): 列表中的每個元素生成一行

  • explode(MAP): map中每個key-value對,生成一行,key為一列,value為一列

 

hive> select ip,appname from appinfo LATERAL VIEW explode(ips) tmpappinfo  AS ip limit 2;
10.0.0.212 bmpjob
10.0.0.225 bmpjob

hive使用concat_ws()函數進行列轉行

# 借用concat_ws()和collect_set()函數進行相同列的重覆數據轉換
# collect_set()函數可以將相關列合併成array<>類型;concat_ws()函數會將array<>類型根據指定的分隔符進行合併
## 示例數據
hive> select * from tmp_jiangzl_test;
tmp_jiangzl_test.col1 tmp_jiangzl_test.col2 tmp_jiangzl_test.col3
a b 1
a b 2
a b 3
c d 4
c d 5
c d 6
## 對於以上數據,我們可以將col3列根據列col1和col2進行合併
hive> select col1,col2,concat_ws(',',collect_set(col3)) from tmp_jiangzl_test group by col1,col2;
col1 col2 _c2
a b 1,2,3
c d 4,5,6

2. struct<>類型的使用

數據定義: struct<name:STRING, age:INT>
數據表示: biaoge:18

示例:

# 元數據格式
1,zhou:30
2,yan:30
3,chen:20
# 相關資料庫結構
hive> create table test-struct(id INT, info struct<name:STRING, age:INT>)
> ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
> COLLECTION ITEMS TERMINATED BY ':';
# 載入數據
hive> LOAD DATA LOCAL INPATH '/home/work/data/test5.txt' INTO TABLE test-struct;
# 查詢相關數據
hive> select info.age from test-struct;
Total MapReduce jobs = 1
......
Total MapReduce CPU Time Spent: 490 msec
OK
30
30

3. map<>類型的使用

數據定義: map<string,int>
數據表示: key:value,key:value...
示例:

# 原始數據格式
1 job:80,team:60,person:70
2 job:60,team:80
3 job:90,team:70,person:100

# map結構的表結構創建
hive> create table employee(id string, perf map<string, int>)
> ROW FORMAT DELIMITED
> FIELDS TERMINATED BY '\t'
> COLLECTION ITEMS TERMINATED BY ','
> MAP KEYS TERMINATED BY ':';

# 數據導入
hive> LOAD DATA LOCAL INPATH '/home/work/data/test7.txt' INTO TABLE employee;

# 數據查詢
hive> select perf['person'] from employee;
Total MapReduce jobs = 1
......
Total MapReduce CPU Time Spent: 460 msec
OK
70
NULL

# 使用explode()函數查詢
hive> select explode(perf) as (p_name,p_score) from employee limit 4;
OK
job 80
team 60
person 70

# 使用explode()和lateral view結合查詢
hive> select id,p_name,p_score from employee lateral view explode(perf) perf as p_name,p_score limit 3;
OK
1 job 80
1 team 60
1 person 70

# 使用size()函數查看map結構中的鍵值對個數[也可查看array中的元素個數]
hive> select size(perf) from employee
3
2
3

三、Hive的常用函數

註意:使用show functions可以查看hive支持的相關函數

1. hive常用函數列表

標準函數使用:

函數名作用描述
round()/floor() 可以將double類型轉換為bigint類型
abs() 返回數值的絕對值
ucase() 將字元串轉換成全是大寫字母
reverse() 將字元串進行翻轉
concat() 將輸入的多個字元串當做一個字元串輸出concat('640?wx_fmt=other171

聚合函數使用:

函數名作用描述
sum() 返回所有輸入求和後的值
avg() 計算所有輸入值的平均值
min()/max() 計算輸入值的最大和最小值

註意:聚合方法通常需要和group by語句組合使用

表生成函數:
表生成函數接收零個或者多個輸入,然後產生多列或多行輸出.

函數名作用描述
array() 將函數內容轉換成一個array<>類型
split(array,split) 將array<>類型按照split分割符進行分割成字元串(轉義時使用\進行轉義)
explode() array數據類型作為輸入,對數組中數據進行迭代,返回多行結果
collect_set() 將某欄位的值進行去重彙總,產生Array類型欄位
collect_list() 同collect_set(),但是不會對欄位進行去重
concat_ws(split,struct) 將struct類型的欄位按照split進行分割成字元串(struct僅支持string和array<>類型)
cast(column as type) 轉換數據類型(column列轉換為type類型)

 

註意:當split被包含在""之中的時候需要使用四個\進行轉義[比如在hive -e ""中執行split函數]

## array()函數可以將一列輸入轉換成一個數組輸出
hive> select array(1,2,3) from xuxuebiao;
OK
[1,2,3]
[1,2,3]

## explode()函數以array數據類型作為輸入,對數組中數據進行迭代,返回多行結果
hive> select explode(array(1,2,3)) from xuxuebiao;
OK
1
2
3
## 使用explode()函數查看array中的某個元素
hive> select * from appinfo LATERAL VIEW explode(ips) tmpappinfo AS realid where realid ='10.0.0.125' ;

## collect_set函數
### 該函數的作用是將某欄位的值進行去重彙總,產生Array類型欄位
hive> select * from test;
OK
1 A
1 C
1 B
hive> select id,collect_set(name) from test group by id;
OK
1 ["A","C","B"]


2.常用的條件判斷以及數據清洗函數

在使用hive處理數據過程中,通常我們需要對相關數據進行清洗轉換,此時我們可能會使用一些條件判斷以及預設值處理函數。

函數名作用描述
IF( Test Condition, True Value, False Value ) 判斷條件,滿足即為True值,不滿足即為False值
CASE Statement 多條件判斷
parse_url() 通常用於清洗url相關函數,提供了常用的url解析功能
parse_url_tuple() 同上
regexp_replace() 正則表達式替換
regexp_extract() 正則表達式解析
COALESCE(column,'') hive中的空值轉換(hive中的空值為NULL,而存儲到hdfs中會以\N來存儲)

示例:

# if條件判斷常用於不同規格數據的清洗操作
hive> select ip,if(assign != '分配狀態未知',0,assign) as fenpei from asset ;
OK
10.0.0.1 分配狀態未知

# case多條件判斷
hive> select ip,
case
when assign = '已分配' then 1
when assign = '未分配' then 2
else 0
end
as fenpei
from asset

hive (ods)> select name,salary,
> case when salary < 800 then 'low'
> when salary >= 800 and salary <=5000 then 'middle'
> when salary >5000 and salary <10000 then 'high'
> else 'very high'
> end as bracket
> from emp1;


# parser_url()函數
hive> select parse_url('https://www.baidu.com/s?cl=3&tn=baidutop10&fr=top1000&wd=%E8%BF%AA%E5%A3%AB%E5%B0%BC%E6%94%B6%E8%B4%AD%E7%A6%8F%E5%85%8B%E6%96%AF&rsv_idx=2','HOST') ;
www.baidu.com

# 正則表達式
hive> select regexp_replace('foobar', 'oo|ar', '');
select regexp_replace('foobar', 'oo|ar', '-');
## 輸出第一個回溯引用(.*?)匹配到的內容即the
select regexp_extract('foothebar', 'foo(.*?)(bar)', 1);
## 輸出第而個回溯引用(bar)匹配到的內容即bar
select regexp_extract('foothebar', 'foo(.*?)(bar)', 2);
## 輸出全部內容
select regexp_extract('foothebar', 'foo(.*?)(bar)', 0);


# 清洗組合
select if(4>5,5000,1000),coalesce(null,1,3,5),coalesce(null,null,null,null), case 3 when 1 then 'lala' when 2 then 'chye' else 'abc' end;

3. hive高級函數

row_number() over()

三、hive常用的環境變數

 

環境變數含義
set hive.cli.print.header=true 設置查詢時顯示表頭
set hive.exec.dynamic.partition=true 開啟動態分區
set hive.exec.dynamic.partition.mode=nonstrict 設置動態分區模式為非嚴格
set hive.exec.max.dynamic.partitions.pernode = 1000 設置每個執行MR的節點上最大分區數
set hive.exec.max.dynamic.partitions=1000 設置所有MR節點上最大總分區數
SET SERDEPROPERTIES('serialization.null.format' = '\N') 設置hive空值存儲方式為'\N'(此時存儲在HDFS中時'\N',查詢顯示為NULL)

                   

640?wx_fmt=jpeg

點贊和轉發是最大的支持~


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 基本涉及到了 interface 的方方面面,有例子、有源碼分析、有彙編分析。直接從 10 個問題出發,深度解答。 ...
  • 字元串 name = 'Jim' # name = str('jim') str1 = str(1.1) str2 = str([1, 2,3]) print(f'str1:{str1} ,str1_type:{type(str1)}') print(f'str2:{str2},str2_type: ...
  • import requests from lxml import etree from urllib import parse import os, time def get_page_html(url): '''向url發送請求''' resoponse = session.get(url, he... ...
  • 本博文分析了強調高質量代碼的原因、判別標準;然後從代碼實踐中總結出怎樣寫出高質量的代碼:​:​從基礎的命名到函數、類以及設計模式、面向對象設計的開發原則、一直到最頂層的模式與架構;給閱讀到該博文的開發人員有正確的指引作用,產生共鳴; ...
  • from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.common.keys import Keys from selenium.webdriver.sup... ...
  • requests模塊 一、發送請求 向某個 發送get請求 發送一個post請求 發送其他類型的請求也都可以 二、傳遞url參數 get請求傳遞參數 post請求傳遞參數 三、響應內容 獲取響應的內容 二進位響應內容 json響應內容 四、指定請求頭 五、複雜的post請求 傳遞類似html表單的數 ...
  • 作業完成人: 學號:20181004011,劉飛宇 學號:20181004023,趙盛陽 1:換選擇幾率高 2:①不換選擇幾率為1/3 ②換選擇:若選中汽車,則換選擇後肯定錯誤;若選中羊,則換選擇後必定正確,因為有兩隻羊,所以正確率為2/3; 3: ...
  • Python基礎之if判斷,while迴圈,迴圈嵌套;if判斷包括 if判斷語法,比較運算符,else語句,邏輯運算符,elif語句,if嵌套;while迴圈包括 while語句語法,賦值運算符,迴圈計算,break和continue;迴圈嵌套包括 print函數的end參數,迴圈嵌套使用,字元串中... ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...