Hive是Facebook為了解決海量日志資料的分析而開發的,後來開源給了Apache軟體基金會,可見Apache軟體基金會是個神奇的組織,我們之前學過的很多開源工具都有Apache軟體基金會的身影。
官網定義:
The Apache Hive ™ data warehouse software facilitates reading, writing, and managing large datasets residing in distributed storage using SQL.
此處版本是Hive-1.0.0
Hive的幾個特點
- Hive最大的特點是通過類SQL來分析大資料,而避免了寫MapReduce程式來分析資料,這樣使得分析資料更容易。
- 資料是存儲在HDFS上的,Hive本身并不提供資料的存儲功能
- Hive是将資料映射成資料庫和一張張的表,庫和表的中繼資料資訊一般存在關系型資料庫上(比如MySQL)。
- 資料存儲方面:它能夠存儲很大的資料集,并且對資料完整性、格式要求并不嚴格。
- 資料處理方面:因為Hive語句最終會生成MapReduce任務去計算,是以不适用于實時計算的場景,它适用于離線分析。

Hive的核心
Hive的核心是驅動引擎,驅動引擎由四部分組成:
- 解釋器:解釋器的作用是将HiveSQL語句轉換為文法樹(AST)。
- 編譯器:編譯器是将文法樹編譯為邏輯執行計劃。
- 優化器:優化器是對邏輯執行計劃進行優化。
- 執行器:執行器是調用底層的運作架構執行邏輯執行計劃。
Hive的底層存儲
Hive的資料是存儲在HDFS上的,Hive中的庫和表可以看做是對HDFS上的資料做的一個映射。是以HVIE必須運作在一個Hadoop的叢集上的
Hive語句執行過程
Hive中的執行器,是将最終要執行的MapReduce程式放到YARN上以一系列Job的方式去執行。
Hive的中繼資料存儲
Hive的中繼資料是一般是存儲在MySQL這種關系型資料庫上的,Hive和MySQL之間通過MetaStore服務互動。
- Hive用戶端
Hive有很多種用戶端。
- cli指令行用戶端:采用互動視窗,用hive指令行和Hive進行通信。
- HiveServer2用戶端:用Thrift協定進行通信,Thrift是不同語言之間的轉換器,是連接配接不同語言程式間的協定,通過JDBC或者ODBC去通路Hive。
- HWI用戶端:hive自帶的一個用戶端,但是比較粗糙,一般不用。
- HUE用戶端:通過Web頁面來和Hive進行互動,使用的比較多。
基本的資料類型
DDL文法
建立資料庫
建立一個資料庫會在HDFS上建立一個目錄,Hive裡資料庫的概念類似于程式中的命名空間,用資料庫來組織表,在大量Hive的情況下,用資料庫來分開可以避免表名沖突。Hive預設的資料庫是default。
建立資料庫例子:
hive> create database if not exists user_db;
檢視資料庫定義
hive> describe database user_db;
OK
user_db hdfs://bigdata-51cdh.chybinmy.com:8020/user/hive/warehouse/user_db.db hadoop USER
user_db是資料庫名
hdfs://bigdata-51cdh.chybinmy.com:8020/user/hive/warehouse/userdb.db 是userdb庫對應的存儲資料的HDFS上的根目錄。
檢視資料庫清單
hive> show databases;
OK
user_db
default
建立資料庫
hive> create table if not exists userinfo
> (
> userid int,
> username string,
> cityid int,
> createtime date
> )
> row format delimited fields terminated by '\t'
> stored as textfile;
OK
Time taken: 2.133 seconds
建立分區表
Hive查詢一般是掃描整個目錄,但是有時候我們關心的資料隻是集中在某一部分資料上,比如我們一個Hive查詢,往往是隻是查詢某一天的資料,這樣的情況下,可以使用分區表來優化,一天是一個分區,查詢時候,Hive隻掃描指定天分區的資料。
普通表和分區表的差別在于:一個Hive表在HDFS上是有一個對應的目錄來存儲資料,普通表的資料直接存儲在這個目錄下,而分區表資料存儲時,是再劃分子目錄來存儲的。一個分區一個子目錄。主要作用是來優化查詢性能。
create table user_action_log
(
companyId INT comment '公司ID',
userid INT comment '銷售ID',
originalstring STRING comment 'url',
host STRING comment 'host',
absolutepath STRING comment '絕對路徑',
query STRING comment '參數串',
refurl STRING comment '來源url',
clientip STRING comment '用戶端Ip',
cookiemd5 STRING comment 'cookiemd5',
timestamp STRING comment '通路時間戳'
)
partitioned by (dt string)
row format delimited fields terminated by ','
stored as textfile;
這個例子中,這個日志表以dt字段分區,dt是個虛拟的字段,dt下并不存儲資料,而是用來分區的,實際資料存儲時,dt字段值相同的資料存入同一個子目錄中,插入資料或者導入資料時,同一天的資料dt字段指派一樣,這樣就實作了資料按dt日期分區存儲。
當Hive查詢資料時,如果指定了dt篩選條件,那麼隻需要到對應的分區下去檢索資料即可,大大提高了效率。是以對于分區表查詢時,盡量添加上分區字段的篩選條件。
建立桶表
桶表也是一種用于優化查詢而設計的表類型。建立通表時,指定桶的個數、分桶的依據字段,hive就可以自動将資料分桶存儲。查詢時隻需要周遊一個桶裡的資料,或者周遊部分桶,這樣就提高了查詢效率。舉例:
create table user_leads
(
leads_id string,
user_id string,
user_id string,
user_phone string,
user_name string,
create_time string
)
clustered by (user_id) sorted by(leads_id) into 10 buckets
row format delimited fields terminated by '\t'
stored as textfile;
對這個例子的說明:
clustered by是指根據userid的值進行哈希後模除分桶個數,根據得到的結果,确定這行資料分入哪個桶中,這樣的分法,可以確定相同userid的資料放入同一個桶中。而經銷商的訂單資料,大部分是根據user_id進行查詢的。這樣大部分情況下是隻需要查詢一個桶中的資料就可以了。
sorted by 是指定桶中的資料以哪個字段進行排序,排序的好處是,在join操作時能獲得很高的效率。
into 10 buckets是指定一共分10個桶。
在HDFS上存儲時,一個桶存入一個檔案中,這樣根據user_id進行查詢時,可以快速确定資料存在于哪個桶中,而隻周遊一個桶可以提供查詢效率
參考資料: