Hive

為什么要有Hive?

在使用Hadoop的過程中,大家都會感覺每次都要寫MR程序才能操作到HDFS的文件,太麻煩了,而且如果項目又趕,項目人員不會寫MR程序,還要花費大量的時間去學,但是我是知道文件內容,是用什么分割的,分割后的每一列是什么意思,感覺好像關系型數據庫。

于是有群人就有了個想法,既然我知道了這些數據分割后的每一列數據的意義,那么能不能把關系型數據庫的SQL解析器搬過來呢?

并把這個解析的映射改為MR程序的映射,用戶只要按照定義好的語法去寫,我就給你解析成對應的MR程序去運行。


什么是Hive?

????? Hive是基于Hadoop的數據倉庫工具,將結構化的數據映射成一張數據庫表,并提供類似SQL查詢功能,稱為HQL,本質就是封裝MR程序。


數據庫和數據倉庫區別(概念)

假設商店場景,數據庫是存儲小物品,而且還是歸類好的物品,并且是庫存不夠的時候就可以很快的就拿到了。

數據倉庫是存儲了一堆的東西,包括已經過期,準備回收的商品,而且很大,并且還可以存儲和數據庫存儲的東西,所相關的東西,比如牛奶賣出去了,這個大的牛奶盒子這些。

數據庫就是存儲存儲定向的數據,如商品的最新信息,畢竟商品的價格每天都會變。

數據倉庫存儲類似歷史數據或主題數據,如,訂單相關的物流信息,商品的歷史價格這些,而且和業務系統不一定完全一樣,主要用于統計、數據分析等



元數據是什么?

????? 元數據就是一個東西的描述信息,比如衣柜,衣柜的外觀、大小、材質、容量、衣柜的哪一格存放了什么東西等等,這些就是元數據。



特點

????? 可擴展性:Hive可以自由的擴展集群規模,一般情況下不需要重啟服務。

????? 延展性:支持用戶自定義函數。

????? 容錯性:節點出問題了,HQL依然可以完成。



組成

用戶接口

CLI:shell命令行

JDBC/ODBC:Hive的Java實現

WebGUI:瀏覽器訪問


元數據存儲

Hive將元數據存儲在數據庫中,Hive中的元數據包括表的名稱、列、分區、屬性、是否是外部表、所在目錄等等



解析

????? 解析器、編譯器、優化器完成HQL查詢語句到詞法解析、語法解析,編譯、優化、查詢計劃生成,查詢計劃是存儲在HDFS,之后調用MR執行。




Hive與傳統數據庫對比

?Hive傳統數據庫

查詢語言HQLSQL

數據存儲HDFSRaw Device or LocalFS

執行MRExecutor

執行延遲高低

數據量多少

索引0.8版本(位圖索引)復雜



Hive數據存儲

DB(數據庫):HDFS下的/user/hive/warehouse文件夾

????? Table(內部表):HDFS下/user/hive/warehouse/數據庫/表,表刪除后對應的文件夾也刪除

????? External Table(外部表):類似Table,就是數據存放位置可以任意指定路徑,刪除后,位于HDFS中的文件不會給刪除。

????? Partition(分區):HDFS下/user/hive/warehouse/數據庫/表/區。

?????????????????????????????????? 分區是一種邏輯性和物理上的優化,以空間換取時間,把一個表的數據切分成兩個進行存儲,這個切分可能是按照時間做切割,后面再查詢的時候,內部會根據條件去判斷要到哪個文件夾去找數據。

????? Bucket在HDFS中同一個表目錄下根據Hash散列后的不同文件,類似10%2=0,存儲到文件1,=1存儲到文件2,=2存儲到文件3…



使用

bin/hive本地客戶端

??????????? bin/hive -e "select * from庫名.表名;":執行執行

????? ????? bin/hive-e "use庫名;select * from表名;":直接執行

????? ????? bin/hive-f文件.hql:將復雜的hql語句放到文件內,并執行

?

????? bin/hiveserver2開啟遠程服務

??????????? 其他機器啟動:bin/beeline

??????????? 其他機器連接:!connectjdbc:hive2://hadoop-s01.levi.com:10000

????? cat ./hivehistory使用過的歷史HQL命令



配置文件常用項(hive-site.xml)

?javax.jdo.option.ConnectionURL

?jdbc:mysql://localhost:3306/metastore?createDatabaseIfNotExist=true


?javax.jdo.option.ConnectionDriverName

?com.mysql.jdbc.Driver


?javax.jdo.option.ConnectionUserName

?root


?javax.jdo.option.ConnectionPassword

?root


? hive.cli.print.header

?true


?hive.cli.print.current.db

?true


<!-- 簡單的查詢不走mapreduce -->

?hive.fetch.task.conversion

?more


?hive.server2.thrift.port

?10000


?hive.server2.thrift.bind.host

?localhost


? hive.server2.long.polling.timeout

?5000



Hive函數


數據類型

數值

類型支持范圍

TINYINT1字節帶符號整數,從-128到127

SMALLINT2字節帶符號整數,從-32,768到32,767

INT/INTEGER4字節帶符號整數,從-2,147,483,648到2,147,483,647

BIGINT8字節帶符號整數,從-9,223,372,036,854,775,808到9,223,372,036,854,775,807

FLOAT4字節單精度浮點數

DOUBLE8字節雙精度浮點數

DOUBLE精度

DECIMAL十進制數據類型在Hive

? 0.11.0 (Hive -2693)中引入,在Hive 0.13.0 (Hive -3976)中進行了修改。


日期

類型支持版本

TIMESTAMP注意:只能從Hive 0.8.0開始使用

DATE注意:只能從Hive 0.12.0開始使用

INTERVAL注意:只能從Hive 1.2.0開始使用


其他

類型支持版本

arraysARRAY(data_type)注:Hive0.14允許負值和非常量表達式。

mapsMAP(primitive_type,? data_type)注:Hive0.14允許負值和非常量表達式。

structsSTRUCTcol_name? : data_type [COMMENT col_comment], …)

unionUNIONTYPE(data_type,? data_type, …)注意:只能從Hive

? 0.7.0開始使用。

string字符串?

?

ARRAYARRAY類型是由一系列相同數據類型的元素組成,這些元素可以通過下標來訪問。比如有一個ARRAY類型的變量fruits,它是由['apple','orange','mango']組成,那么我們可以通過fruits[1]來訪問元素orange,因為ARRAY類型的下標是從0開始的

[if !supportLineBreakNewLine]

[endif]

MAPMAP包含key->value鍵值對,可以通過key來訪問元素。比如”userlist”是一個map類型,其中username是key,password是value;那么我們可以通過userlist['username']來得到這個用戶對應的password;

[if !supportLineBreakNewLine]

[endif]

STRUCTSTRUCT可以包含不同數據類型的元素。這些元素可以通過”點語法”的方式來得到所需要的元素,比如user是一個STRUCT類型,那么可以通過user.address得到這個用戶的地址。

[if !supportLineBreakNewLine]

[endif]

UNIONUNIONTYPE,他是從Hive 0.7.0開始支持的。



常用HQL

創建數據庫:CREATE DATABASE IF NOT EXISTS levi;

?????

????? 設置變量臨時生效:set hive.cli.print.header=false

?????

創建表:create table if not exists test(idstring,name string,sex string) row format delimited fields terminated by '\t';

????? 創建表:create table newtb as select * fromdb.tname

????? 創建表:create table newtb like db.tname

????? 創建外部表:create external table test2(id int,namestring) row format delimited fields terminated by '\t'

????? 創建表(分區):create table if not exists levi.t_partition(id string,

name string)partitioned by (datestring,hour string)

row format delimited fields terminated by'\t';

????? 創建表(分桶):create table people(id string,name string)clusteredby(id) sorted by (id) into 3 buckets row format?delimited fields terminated by '\t';

????? 創建表(正則):

create table IF NOT EXISTS test (

id string,

name string

)

ROW FORMAT SERDE'org.apache.hadoop.hive.serde2.RegexSerDe'

WITH SERDEPROPERTIES (

"input.regex" = "(\"[^ ]*\")(\"-|[^ ]*\") (\"[^\]]*\") (\"[^\"]*\")(\"[0-9]*\") (\"[0-9]*\") (-|[^ ]*) (\"[^ ]*\")(\"[^\"]*\") (-|[^ ]*) (\"[^ ]*\")"

)

STORED AS TEXTFILE;


????? 查看表信息:desc formatted tbname


????? 導入數據(本地):load data local inpath '/local_path/file' into table 表名;

????? 導入數據(本地)(覆蓋):load data local inpath '/local_path/file'

overwrite into table 表名;

????? 導入數據(HDFS):load

data inpath '/local_path/file' into table 表名;

????? 導入數據:insert into table 表名select * from tbname;

????? 導入數據:insert overwrite into table 表名select * from tbname;

????? 導入數據(分區):load data local inpath'/opt/module/hive-hql/1999092919' into table levi.t_partitionpartition(date='19990929',hour='19');

????? 導出(本地):insert overwrite local directory"/opt/module/hive-hql/data_dir/"row format delimited fieldsterminated by '\t' select * from levi.tname;

????? 導出(HDFS):insertoverwrite directory "path/" select * from levi.tbname;


????? 自定義UDF函數:

public?class?ToLowerCase?extends?UDF {

?public?Text evaluate(Text str) {

?if(null?== str) {

?return?null;

????????? }

?if(null?!= str && str.toString().length() <= 0) {

?return?null;

????????? }

?return?new?Text(str.toString().toLowerCase());

???? }

}


????? 添加到hive的classpath:add jar /opt/lowercase.jar????

????? 添加到Hive函數列表:create

temporary function 函數名as

'包名.類名'

????? 運行函數:select 函數名(name) from student;



排序

????? order by全局排序,會強行的把reducer改為一個,就算分桶了,還是查詢所有數據。

????? sort by數據進入reducer前完成排序,因此使用sort by排序,并設置mapred.reduce.tasks>1,則sort by保證每個reducer輸出有序,不保證全局有序,就算是對每一個reduce內部數據進行排序。

????? distribute by根據ditribute by指定的字段,將數據分發不同reducer,而且分發算法是hash散列算法。

????? cluster by就是sort by + distribute by。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Hive是什么? Hive是一種基于Hadoop的數據庫技術并提供完整的sql查詢功能, . HIVE能做什么? ...
    日出卡爾閱讀 2,738評論 0 0
  • Hive是基于Hadoop的一個數據倉庫工具,可以將結構化的數據文件映射為一張數據庫表,并提供類SQL查詢功能。本...
    felix521閱讀 1,325評論 0 0
  • Hive是構建在Hadoop HDFS上得一個數據倉庫 數據倉庫是一個面向主題的、集成的、不可更新的、隨時間不變化...
    Sx_Ren閱讀 964評論 0 9
  • hive.ddl.output.format:hive的ddl語句的輸出格式,默認是text,純文本,還有json...
    博弈史密斯閱讀 1,971評論 0 6
  • 數組去重可以有六種方法 聲明:所有文章都是轉載整理的,只是為了自己學習,方便自己觀看,如有侵權,請立即聯系我,謝謝...
    是河兔兔啊閱讀 294評論 0 0