萬字長文詳解 Hive 入門基礎

1.Hive 簡介

1.1 簡介

而 Hive 主要解決**「存儲和計算問題」**。

Hive 是由 Facebook 開源的基於 Hadoop 的數據倉庫工具,用於解決海量**「結構化日誌」**的數據統計。

簡單來說,Hive 是在 Hadoop 上**「封裝了一層 HQL 的接口」**,這樣開發人員和數據分析人員就可以使用 HQL 來進行數據的分析,而無需關注底層的 MapReduce 的編程開發。

所以 Hive 的本質是**「將 HQL 轉換成 MapReduce 程序」**。

1.2 優缺點

1.2.1 優點

1.2.2 缺點

1.3 架構原理

放上一張很經典的 Hive 架構圖:

如上圖所示:

所以 Hive 查詢的大致流程爲:通過用戶交互接口接收到 HQL 的指令後,經過 Driver 結合元數據進行類型檢測和語法分析,並生成一個邏輯方法,通過進行優化後生成 MapReduce,並提交到 Hadoop 中執行,並把執行的結果返回給用戶交互接口。

1.4 與 RDBMS 的比較

Hive 採用類 SQL 的查詢語句,所以很容易將 Hive 與關係型數據庫(RDBMS)進行對比。但其實 Hive 除了擁有類似 SQL 的查詢語句外,再無類似之處。我們需要明白的是:數據庫可以用做 online 應用;而 Hive 是爲數據倉庫設計的。

Hive/RDBMS

NxVAiq

2.Hive 基本操作

2.1 Hive 常用命令

在終端輸入 hive -help 會出現:

usage: hive
 -d,--define <key=value>          Variable substitution to apply to Hive
                                  commands. e.g. -d A=B or --define A=B
    --database <databasename>     Specify the database to use
 -e <quoted-query-string>         SQL from command line
 -f <filename>                    SQL from files
 -H,--help                        Print help information
    --hiveconf <property=value>   Use value for given property
    --hivevar <key=value>         Variable substitution to apply to Hive
                                  commands. e.g. --hivevar A=B
 -i <filename>                    Initialization SQL file
 -S,--silent                      Silent mode in interactive shell
 -v,--verbose                     Verbose mode (echo executed SQL to the
                                  console)

常用的兩個命令是 "-e" 和 "-f":

hive -e "select * from teacher;"
hive -f /opt/module/datas/hivef.sql

2.2 本地文件導入 Hive 表中

首先需要創建一張表:

create table student(
  id int, 
  name string
) 
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';

簡單介紹下字段:

除此之外,還有其他的分割符設定:

這裏需要注意的是 ROW FORMAT DELIMITED 必須在其它分隔設置之前;LINES TERMINATED BY 必須在其它分隔設置之後,否則會報錯。

然後,我們需要準備一個文件:

# stu.txt
1 Xiao_ming
2 xiao_hong
3 xiao_hao

需要注意,每行內的字段需要用 '\t' 進行分割。

接着需要使用 load 語法加載本地文件,load 語法爲:

load data [local] inpath 'filepath' [overwrite] into table tablename [partition (partcol1=val1,partcol2=val2...)]
hive> load data local inpath '/Users/***/Desktop/stu1.txt' into table student;

最後查看下數據:

hive> select * from student;
OK
1 Xiao_ming
2 xiao_hong
3 xiao_hao
Time taken: 1.373 seconds, Fetched: 3 row(s)

2.3 Hive 其他操作

不過這種區別只是在舊版本中有,兩者在新版本已經沒有區別了。

在 hive cli 中可以用以下命令查看 hdfs 文件系統和本地文件系統:

dfs -ls /;  # 查看 hdfs 文件系統
! ls ./;  # 查看本地文件系統

用戶根目錄下有一個隱藏文件記錄着 hive 輸入的所有歷史命令:

cat ./hivehistory

注意:hive 語句不區分大小寫。

3.Hive 常見屬性配置

3.1 數據倉庫位置

Default 的數據倉庫原始位置是在 hdfs 上的:/user/hive/warehoues 路徑下。如果某張表屬於 Default 數據庫,那麼會直接在數據倉庫目錄創建一個文件夾。

我們以剛剛創建的表爲例,來查詢其所在集羣位置:

hive> desc formatted student;
OK
# col_name             data_type            comment
id                   int
name                 string

# Detailed Table Information
Database:            default
OwnerType:           USER
Owner:               **
CreateTime:          Fri Jul 17 08:59:14 CST 2020
LastAccessTime:      UNKNOWN
Retention:           0
Location:            hdfs://localhost:9000/user/hive/warehouse/student
Table Type:          MANAGED_TABLE
Table Parameters:
 bucketing_version    2
 numFiles             1
 numRows              0
 rawDataSize          0
 totalSize            34
 transient_lastDdlTime 1594948899

# Storage Information
SerDe Library:       org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe
InputFormat:         org.apache.hadoop.mapred.TextInputFormat
OutputFormat:        org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat
Compressed:          No
Num Buckets:         -1
Bucket Columns:      []
Sort Columns:        []
Storage Desc Params:
 field.delim          \t
 serialization.format \t
Time taken: 0.099 seconds, Fetched: 32 row(s)

可以看到,Table Information 裏面有一個 Location,表示當前表所在的位置,因爲 student 是 Default 數據倉庫的,所以會在 '/user/hive/warehouse/' 路徑下。

如果我們想要修改 Default 數據倉庫的原始位置,需要在 hive-site.xml(可以來自 hive-default.xml.template)文件下加入如下配置信息,並修改其 value:

<property> 
  <name>hive.metastore.warehouse.dir</name> 
  <value>/user/hive/warehouse</value> 
  <description>location of default database for the warehouse</description> 
</property>

同時也需要給修改的路徑配置相應的權限:

hdfs dfs -chmod g+w /user/hive/warehouse

3.2 查詢信息顯示配置

我們可以在 hive-site.xml 中配置如下信息,便可以實現顯示當前數據庫以及查詢表的頭信息:

<property> 
  <name>hive.cli.print.header</name> 
  <value>true</value> 
</property>

<property> 
  <name>hive.cli.print.current.db</name> 
  <value>true</value> 
</property>

當然我們也可以通過 set 命令來設置:

set hive.cli.print.header=true;  # 顯示錶頭
set hive.cli.print.current.db=true;  # 顯示當前數據庫

看下前後的對比:

# 前
hive> select * from studenT;
OK
1 Xiao_ming
2 xiao_hong
3 xiao_hao
Time taken: 0.231 seconds, Fetched: 3 row(s)

# 後
hive (default)>  select * from student;
OK
student.id student.name
1 Xiao_ming
2 xiao_hong
3 xiao_hao
Time taken: 0.202 seconds, Fetched: 3 row(s)

3.3 參數配置方式

可以用 set 查看當前所有參數配置信息:

hive> set

但是一般不這麼玩,會顯示很多信息。

通常配置文件有三種方式:

上述三種設定方式的優先級依次遞增。即配置文件 < 命令行參數 < 參數聲明。注意某些系統級的參數,例如 log4j 相關的設定,必須用前兩種方式設定,因爲那些參數的讀取在會話建立以前已經完成了。

4.Hive 數據類型

4.1 基本數據類型

Hive 數據類型/Java 數據類型/長度

hbc5m5

Hive 的 String 類型相當於數據庫的 varchar 類型,該類型是一個可變的字符串,不過它不能聲明其中最多能存儲多少個字符,理論上它可以存儲 2GB 的字符數。

4.2 集合數據類型

數據類型/描述/語法示例

O84FSw

Hive 有三種複雜數據類型 ARRAY、MAP、STRUCT。ARRAY 和 MAP 與 Java 中的 Array 和 Map 類似,而 STRUCT 與 C 語言中的 Struct 類似,它封裝了一個命名字段集合,複雜數據類型允許任意層次的嵌套。

案例實操:

  1. 假設某表有如下一行,我們用 JSON 格式來表示其數據結構。在 Hive 下訪問的格式爲:
{
  "name""songsong",
  "friends"["bingbing" , "lili"] , //列表 Array, 
  "children"{   //鍵值 Map,
    "xiao song": 18 ,
    "xiaoxiao song": 19 
  },
  "address"{  //結構 Struct,
    "street""hui long guan" ,
    "city""beijing" 
  }
}
  1. 基於上述數據結構,我們在 Hive 裏創建對應的表,並導入數據。創建本地測試文件 text.txt:
songsong,bingbing_lili,xiao song:18_xiaoxiao song:19,hui long guan_beijing yangyang,caicai_susu,xiao yang:18_xiaoxiao yang:19,chao yang_beijing

注意:MAP,STRUCT 和 ARRAY 裏的元素間關係都可以用同一個字符表示,這裏用 “_”。

  1. Hive 上創建測試表 test:
create table test( 
  name string, 
  friends array<string>, 
  children map<string, int>, 
  address struct<street:string, city:string> 
)
row format delimited
fields terminated by ',' 
collection items terminated by '_' 
map keys terminated by ':'
lines terminated by '\n';

字段解釋:

  1. 導入文本數據到測試表中:
hive (default)> load data local inpath '/Users/chenze/Desktop/test.txt' into table test;
  1. 訪問三種集合列裏的數據:

先查看下數據:

hive (default)select * from test;
OK
test.name test.friends test.children test.address
songsong ["bingbing","lili"] {"xiao song":18,"xiaoxiao song":19} {"street":"hui long guan","city":"beijing yangyang"}
Time taken: 0.113 seconds, Fetched: 1 row(s)

查看 ARRAY,MAP,STRUCT 的訪問方式:

hive (default)select friends[1],children['xiao song'],address.city from test where ;
OK
_c0 _c1 city
lili 18 beijing yangyang
Time taken: 0.527 seconds, Fetched: 1 row(s)

4.3 數據類型轉化

Hive 的原子數據類型是可以進行隱式轉換的,類似於 Java 的類型轉換,例如某表達式使用 INT 類型,TINYINT 會自動轉換爲 INT 類型,但是 Hive 不會進行反向轉化,例如,某表達式使用 TINYINT 類型,INT 不會自動轉換爲 TINYINT 類型,它會返回錯誤,除非使用 CAST 操作。

  1. 隱式類型轉換規則如下

  2. 任何整數類型都可以隱式地轉換爲一個範圍更廣的類型,如 TINYINT 可以轉換 成 INT,INT 可以轉換成 BIGINT;

  3. 所有整數類型、FLOAT 和 STRING 類型都可以隱式地轉換成 DOUBLE;

  4. TINYINT、SMALLINT、INT 都可以轉換爲 FLOAT;

  5. BOOLEAN 類型不可以轉換爲任何其它的類型。

  6. 可以使用 CAST 操作顯示進行數據類型轉換

例如 CAST('1' AS INT) 將把字符串 '1' 轉換成整數 1;如果強制類型轉換失敗,如執行 CAST('X' AS INT),表達式返回空值 NULL。

  1. 數據組織 =======

1、Hive 的存儲結構包括**「數據庫、表、視圖、分區和表數據」**等。數據庫,表,分區等等都對 應 HDFS 上的一個目錄。表數據對應 HDFS 對應目錄下的文件。

2、Hive 中所有的數據都存儲在 HDFS 中,沒有專門的數據存儲格式,因爲 「Hive 是讀模式」 (Schema On Read),可支持 TextFile,SequenceFile,RCFile 或者自定義格式等。

3、 只需要在創建表的時候告訴 Hive 數據中的**「列分隔符和行分隔符」**,Hive 就可以解析數據

4、Hive 中包含以下數據模型:

5、Hive 的元數據存儲在 RDBMS 中,除元數據外的其它所有數據都基於 HDFS 存儲。默認情 況下,Hive 元數據保存在內嵌的 Derby 數據庫中,只能允許一個會話連接,只適合簡單的 測試。實際生產環境中不適用,爲了支持多用戶會話,則需要一個獨立的元數據庫,使用 MySQL 作爲元數據庫,Hive 內部對 MySQL 提供了很好的支持。

6、Hive 中的表分爲內部表、外部表、分區表和 Bucket 表

使用外部表的場景是針對一個數據集有多個不同的 Schema

通過外部表和內部表的區別和使用選擇的對比可以看出來,hive 其實僅僅只是對存儲在 HDFS 上的數據提供了一種新的抽象。而不是管理存儲在 HDFS 上的數據。所以不管創建內部 表還是外部表,都可以對 hive 表的數據存儲目錄中的數據進行增刪操作。

6.Reference

  1. 尚硅谷 Hive 教程 (新版 hive 框架詳解)

  2. Hive 學習之路 (一)Hive 初識

  3. Hive 內部表與外部表的區別

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/2zyXgAvpB14qi-8WAabcIg