您好,登錄后才能下訂單哦!
這篇文章主要為大家展示了“hive是干什么的”,內容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領大家一起研究并學習一下“hive是干什么的”這篇文章吧。
Hive是啥?
Hive是建立在hadoop上的數據倉庫基礎框架,主要用于分析與統計數據。他也是一個Sql解析引擎,將Sql語句轉換成mr程序來運行,從而得到統計數據。他的語法大部分遵循Sql99,所以對有著數據庫經驗的人來說很友好。他們不用寫繁瑣的MR程序,通過sql語句即可得到所需的數據。Hive中的表就是hdfs上的目錄,一個表名對應一個目錄名,數據以文件形式存放在目錄下。因為hive存儲基于hdfs,所以依賴于hadoop,在沒有hadoop的環境下hive是跑不了的。它并沒有專門的存儲格式,卻有著存儲結構,比如數據庫,表,視圖之類。
Hive的系統架構。
首先對外提供了三種用戶接口,CLI,JDBC/ODBC,WebUI,所以用戶可通過三種形式來操作hive。用戶訪問了,必然執行sql語句,所以hive要有編譯器,解釋器,優化器,執行器。接著生成了MR任務,也就是執行計劃,去訪問ResourceManger和NameNode來處理程序。其中hive的MetaStore,也就是元數據存儲依賴于數據庫。默認是自帶的derby數據庫,可是這個數據庫只支持一個會話,所以可通過更改配置將其更改為用MySql存儲。
Hive中sql的執行過程
首先用戶通過接口向hive提交了sql語句,接著發給驅動來解析語句,然后交給編譯器編譯語句,再找metastore查詢涉及到的元數據,生成執行計劃交還給驅動,驅動把計劃交給執行引擎執行,執行引擎如果發現這是類似于ddl語句,則要往metastore寫入元數據,如果是涉及到計算的語句,如count(*)之類的則要交給resourcemanger來執行mr程序,如果是查詢字段之類的,則直接找namenode拿到所需數據即可。等到程序執行完或者數據拿到,則將執行結果交換執行引擎,執行引擎給用戶接口。
Hive三種用戶接口之CLI
其實也就是命令行模式,直接執行hive,或者執行hive --service cli。這樣就可打開hive命令行。你可以輸入show tables;或者create table語句來驗證是否成功。(注意,上面說到hive表其實就是hdfs的目錄,該目錄的路徑是由你的配置文件項hive.metastore.warehouse.dir所指定的)。在你啟動hive的時候,你可以加一些參數,來多功能的使用。比如你用 hive -d name=xiaoming,則就等于設置了一個name變量,變量值為xiaoming,在hive中可以調用該變量${name}。或者說你就想執行一條語句,并不想進入hive命令行,你可以 hive -e “show tables”。或者你想把執行結果寫入文件中,則hive -e “show tables”> a.txt。舉例如下
$>hive -e "" 不用進入hive界面,在雙引號里使用hql語句即可執行,省略了開啟hive的時間。不過執行完還在linux界面
$>hive -e "">aaa 同上,不過就是把執行的結果寫入aaa中
$>hive -S -e "">aaa 同上,加了個靜默模式,就是少了一些日志提示,比如執行的時間什么的,大量操作的話,可以省略部分時間。
$>hive -f file File用一個寫入了hql語句的文件的位置代替,然后就執行了。
$>hive -i /home/my/hive-init.sql 就是執行完過后不是回到了linux界面,而使留在了hive界面
hive>source file 跟-f差不多,不過是在hive界面執行。
你也可以用 hive --hiveconf 加上要指定的配置文件項來在當前會話中使用你指定的配置,如
hive --hiveconf hive.cli.print.current.db=true;
你也可以在hive命令行下使用set命令來完成與hiveconf相同的功能,如set hive.cli.print.current.db=true;
如果你覺得這樣配置好麻煩,想一啟動的時候就自動應用這些配置,那么你可以在你操作系統的用戶目錄下,也就是你用cd命令到的目錄下,建立文件.hiverc(不要忘記.)。文件內容就是set命令內容。
hive用戶接口之JDBC
用這種當時的時候,注意看自己的hive是1版本還是2版本,可以通過hive下的bin看是hiveserver還是hiveserver2來確定。
運行代碼之前需要在命令行中啟動服務,hive --service hiveserver2,代碼如下
package com.shixin.hivejdbc; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; public class Hivetest { public static Connection getConnection(){ Connection con=null; try { //若是1版本,則為org.apache.hadoop.hive.jdbc.HiveDriver Class.forName("org.apache.hive.jdbc.HiveDriver"); //注意這里是hive2 con=DriverManager.getConnection("jdbc:hive2://115.28.138.100:10000/default", "hadoop", "hadoop"); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return con; } public static void main(String[] args) { Connection con=getConnection(); Statement sta=null; if(con!=null){ try { sta=con.createStatement(); ResultSet rs=sta.executeQuery("show tables"); while(rs.next()){ System.out.println(rs.getString(1)); } } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
hive之復合數據類型
hive中的基本數據類型與mysql大致形同,主要是多出了三種復合數據類型。分別為Array,Struct,Map。如何使用請看例子。
建表
create table t8(
id int,
info struct<name:string,age:int>,
subject array<int>,
scores map<string,float>)
row format delimited
fields terminated by '\t'
collection items terminated by ','
map keys terminated by ':'
;
(field那句表示字段分隔符,collection表示復合數據類型中內部分隔符,map表示map類型的鍵值對分隔符)
導入數據
load data local inpath '/home/hadoop/a.txt' into table t8;
其中a.txt數據為
1 sx,21 23,45,32,45 english:94.2,math:99
2 shuainan,22 43,21,32 english:95.2,math:96
查看數據
select * from t8;
t8.id t8.info t8.subject t8.scores
1 {"name":"sx","age":21} [23,45,32,45] {"english":94.2,"math":99.0}
2 {"name":"shuainan","age":22} [43,21,32] {"english":95.2,"math":96.0}
如果分別查詢符合數據類型某個值的話,語句為
select info from t8;
select info.sx from t8;
select info.name from t8;
select subject from t8;
select subject[2] from t8;
select subject[3] from t8;
select scores from t8;
select scores['english'] from t8;
7.hive中的一些ddl語句
數據庫定義,create database。。。(注意一點,hive啟動時默認是default數據庫)
表定義,create table。。。。,當然除了這個基礎語句,還有create table t2 like t1;只復制t1的表結構,不復制數據。
列定義,其實也就是列的修改
hive>ALTER TABLE t3 CHANGE COLUMN old_name new_name String COMMENT '...' AFTER column2;
ALTER TABLE t3 ADD COLUMNS(gender int);
replace(沒有刪除列,不過可以試試replace,不過不建議,因為他就等于重新建立表結構,比如你原有兩個字段,Replace一個字段,replace過后你就只剩一個字段)
8.外部表與內部表
上述的表的定義,是內部表的定義。那么外部表如何定義的呢?
create external table t11 (id int,name string) row format delimited fields terminated by '\t';
對,僅僅加了個external,查看對應的hdfs的目錄,多了個t11目錄。接著加載數據
load data local inpath '/home/hadoop/aaa' into table t11;
用select查看,可以查看到數據,看hdfs對應的t11目錄下,多了個aaa文件。這一切好像都和內部表一樣啊。那么他們兩個的區別是什么?我們對內部表和外部表都用drop table操作,結果發現,內部表的hdfs上的表目錄消失,而外部表的表目錄數據依舊存在。所以,我們可知 刪除外部表只刪除metastore的元數據,不刪除hdfs中的表數據(就是warehouse目錄下的)。
當表的定義語句是這樣的
hive> create external table exter_table(
> id int,
> name string,
> age int,
> tel string)
> location '/home/wyp/external';
也就是說你加了location,指定了表的存放路徑,此時不論有沒有external(也就是說不論是內部表還是外部表),他會在指定路徑創建指定文件夾,而不是說像原來一樣在warehouse下以表名為目錄創建。此時如果你用load命令導入數據,數據文件會存放到你指定的路徑下。
9.分區表
分區表也就是把數據分類,分組,類似于groupby,將不同的分區以不同的文件夾形式表現出來。它的意義就是優化查詢。查詢時如果用分區字段,則會加快查詢速度。
創建分區表
create table t12 (id int,name string) partitioned by (date string) row format delimited fields terminated by '\t';
添加分區
alter table t12 add partition(data='20160103');
alter table t12 add partition(date='20160102');
此時,t12目錄下多出了data=20160102和 data=20160103文件夾。
加載數據
load data local inpath '/home/hadoop/aaa' into table t12 partition(date='20160103');
10.視圖和索引
hive中也可以像mysql一樣創建視圖和索引
create view v1 AS select t1.name from t1;
創建索引
create index t1_index on table t1(name)as 'org.apache.hadoop.hive.ql.index.compact.CompactIndexHandler' with deferred rebuild in table t1_index_table; ( as指定索引器)
重建索引
alter index t1_index on t1 rebuild;(當數據有更改時,需要重建索引)
顯示索引
show formatted index on t1;
刪除索引
drop index if exists t1_index on t1;
11.裝載數據的方式
從文件中裝載數據
hive>LOAD DATA [LOCAL] INPATH '...' [OVERWRITE] INTO TABLE t2 [PARTITION (province='beijing')];(不加local則從hdfs上面取,overwrite是覆蓋的意思,如果是分區表則要加上partition)
通過查詢表裝載數據
hive>INSERT OVERWRITE TABLE t2 PARTITION (province='beijing') SELECT * FROM xxx
WHERE xxx (同樣,如果你是分區表,分區信息加上,他會把select查詢的數據以文件的形式存放到t2對應的目錄下,你的select語句所查詢的屬性要能和t2對的上)
hive>FROM t4
INSERT OVERWRITE TABLE t3 PARTITION (...) SELECT ...WHERE...
INSERT OVERWRITE TABLE t3 PARTITION (...) SELECT ...WHERE...
INSERT OVERWRITE TABLE t3 PARTITION (...) SELECT ...WHERE... (上面的升級版)
還有一種動態分區加載
hive>INSERT OVERWRITE TABLE t3 PARTITION(province='bj', city)
SELECT t.province, t.city FROM temp t WHERE t.province='bj';
(你的city分區字段屬性要對得上,然后執行后就會在province=bj下創建city=t.city的目錄分區。其中province的值可以不存 在,他會新建。這種情況是不開啟動態分區的時候支持的)
如果你的語句是這樣的
hive>INSERT OVERWRITE TABLE t3 PARTITION(province, city)
此時要開啟動態分區支持
hive>set hive.exec.dynamic.partition=true;
hive>set hive.exec.dynamic.partition.mode=nostrict;
hive>set hive.exec.max.dynamic.partitions.pernode=1000;
12. hive中的函數
hive中有像mysql中的函數,比如max(),min()等。hive中也可以自定義函數,你把所需要的功能用java代碼編好,打jar包即可。具體步奏如下
a)把程序打包放到目標機器上去;
b)進入hive客戶端,添加jar包:hive>add jar /run/jar/udf_test.jar;
c)創建臨時函數:hive>CREATE TEMPORARY FUNCTION add_example AS 'hive.udf.Add';
(add_example是你要取得函數名字,‘’里面的是你的類路徑,比如com.shixin.hive.MyUp)
udf代碼如下(小小的轉換大寫功能)
package com.shixin.hive;
import org.apache.hadoop.hive.ql.exec.UDF;
public class MyUp extends UDF{
public String evaluate(String word){
if(word==null||word.equals("")){
return null;
}else{
return word.toUpperCase();
}
}
}
以上是“hive是干什么的”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。