1 hive簡介
1.1 什麼是Hive?
Hive是基於Hadoop HDFS之上的數據倉庫。
我們可以把數據存儲在這個基於數據的倉庫之中,進行分析和處理,完成我們的業務邏輯。
本質上就是一個數據庫
它可以來保存我們的數據,Hive的數據倉庫與傳統意義上的數據倉庫還有區別。
一般來說,我們也可以基於傳統方式(Oracle或者MySQL數據庫)來搭建這個數據倉庫,這個時候數據倉庫中的數據是保存在Oracle或者MySQL的數據庫當中的。
Hive跟傳統方式是不一樣的,Hive是建立在Hadoop HDFS基礎之上的數據倉庫基礎框架。也就是說
--Hive這個數據倉庫中的數據是保存在HDFS上。
--Hive可以用ETL的方式來進行數據提取轉化加載。
--Hive定義了簡單的類似SQL查詢語言,稱為HQL。
--Hive允許熟悉MapReduce開發者的開發自定義的mapper和reducer來處理內建的mapper和reducer無法完成的複雜的分析工作。
--Hive是SQL解析引擎,它將SQL語句轉移成M/R Job,然後在Hadoop上執行。把執行的結果最終反映給用戶。
--Hive的表其實就是HDFS的目錄,Hive的數據其實就是HDFS的文件
1.2 什麼是數據倉庫?
實際上就是一個數據庫。我們可以利用數據倉庫來保存我們的數據。
與一般意義上的數據庫不同。數據倉庫是一個面向主題的、集成的、不可更新的、隨時間不變化的數據集合,它用於支持企業和組織的決策分析處理。
1)面向主題的:
數據倉庫中的數據是按照一定的主題來組織的。*主題:指的是用戶使用數據倉庫進行決策時所關心的重點方面。
2)集成的:
數據倉庫中的數據來自於分散的操作性的數據,我們把分散性的數據的操作性的數據從原來的數據中抽取出來進行加工和處理,然後滿足一定的要求才可以進入我們的數據倉庫。
3)不可更新的
也就是說數據倉庫主要是為了決策分析所提供數據,所以涉及的操作主要是數據的查詢。我們一般都不會再數據倉庫中進行更新和刪除。
4)隨時間不變化
數據倉庫中的數據是不會隨時間產生變化的集合。
1.3 數據倉庫的結構和建立過程
1)數據源:
有可能來自由業務數據系統(關係型數據庫),文檔資料(csv,txt等),其他數據
2)數據存儲和管理:
俗稱的ETL的過程。
抽取(Extract):把數據源的數據按照一定的方式讀取出來
轉換(Transform):不同數據源的數據它的格式是不一樣的,不一定滿足我們的要求,所以需要按照一定的規則進行轉換。
裝載(Load):將滿足格式的數據存取到數據倉庫之中。
3)數據倉庫引擎:
建立了數據倉庫以後,當然是提供對外的數據服務,所以產生了數據倉庫引擎。
在數據倉庫引擎之中包含有不同的服務器,不同的服務器提供不同的服務。
4)前端展示:
前端展示的數據均來自數據倉庫引擎中的各個服務。而服務又讀物數據倉庫中的數據。
數據查詢
數據報表
數據分析
各類應用
1.4 OLTP應用與OLAP應用
數據處理大致可以分成兩大類
聯機事務處理OLTP(on-line transaction processing):主要面向事務。
聯機分析處理OLAP(on-line analytical processing):主要面向查詢。
OLTP是傳統的關係型數據庫的主要應用。主要是基本的、氣場的事務處理,例如銀行交易。
OLAP是數據倉庫系統的主要應用,支持複雜的分析操作,側重決策支持,並且提供直觀易懂的查詢結果。
OLTP系統強調數據庫內存效率,強調內存各種指標的命令率,強調綁定變量,強調併發操作。
OLAP系統澤強調數據分析,強調SQL執行市場,強調磁盤I/O,強調分區等。
1.5 Hive的體系結構之元數據
Hive將元數據(meta data)存儲在數據庫中(meta store),支持mysql,oracle,derby(默認)等數據庫。
Hive中的元數據包括表的名字,表的列和分區以及屬性,表的屬性(是否為外部表等),表的數據所在目錄等。
1.6 Hive的體系結構之HQL的執行過程
一條HQL語句如何在Hive的數據倉庫當中中進行查詢的?
由解釋器、編譯器、優化器來共同完成HQL查詢語句從詞法解析、語法解析、編譯、優化以及查詢計劃(Plan)的生成。
生成的查詢計劃存儲在HDFS中,並在隨後又MapReduce調用執行。
1.7 Hive的表
1)表
--Table:內部表
--Partition:分區表
--External Table:外部表
--Bucket Table:桶表
2)視圖
是一個邏輯概念,類似於我們的表
3)內部表
--與數據庫中的Table在概念上是類似的。
--每一個Table在Hive中都有一個相應的存儲數據。
--所有的Table數據(不包括External Table)都保存在這個目錄中。
--刪除表的時候,元數據與數據都會被刪除。
創建表的命令:
create table t1 (tid int, tname string, age int;)
創建表的同事插入數據:
create table t4 as select * from sample_data;
變更表結構:如添加列
alter table t1 add columns (qnglish int);
刪除表:會將表移入到回收站當中。
drop table t1;
4)分區表(Partition Table)
--Partition對應於數據庫中的Partition列的密集索引
--在Hive中,表中的一個Partition對應於表下的一個目錄,所有的Partition的數據都存儲在對應的目錄中。
創建一張基於性別的分區表,以逗號分隔:
create table partition_table(sid int, sname string) partitioned by (gender string)
row format delimited fields terminated by ',';
創建之後,查詢一下表的結構可以看分區信息。
向分區表中插入數據
insert into table partition_table partition(gender='M') select sid, sname from student where gender='M';
分區表是非常有用的,當我們的數據量非常大的時候,我們需要按照一定的條件將數據分區,
這樣在我們查詢操作的時候就能降低需要遍歷的記錄數,從而提高查詢的效率。
5)外部表(External Table)
--指向已經在HDFS中存在的數據的表,它也可以來創建Partiton
--它和內部表在元數據的組織上是相同的,也就是說外部表依然是保存在我們的數據庫當中。而實際數據的存儲則有較大的差異。
--外部表"只是一個過程",加載數據和創建表同事完成,並不會移動到數據倉庫目錄中,只是與外部數據建立一個鏈接。當刪除一個外部表時,僅僅刪除該鏈接。
創建外部表
create external table external_student(sid int, sname string, age int) location '/tmp/chenjian/';
*location是HDFS中的路徑。
6)桶表(Bucket Table)
--桶表是對數據進行哈希取值,然後放到不同文件中存儲。相當於oracle中的散列分區表。
桶表中的數據是經過哈希運算之後,將之打散了存在文件當中。這樣的好處是可以避免造成"熱塊"。
創建桶表
create table bucket_table(sid int, sname string, age int) clustered by (sname) into 5 buckets
7)視圖(View)
--視圖是一種虛表,是一個邏輯概念;可以擴越多張表。
--視圖建立在已有表的基礎上,視圖賴以建立的這些表稱為基表。
--視圖可以簡化複雜的查詢。(最大的優點)
創建視圖
create view view_emp as
1.8 測試Hive
1) 創建數據庫
create database userdb;
use userdb;
2) 創建表emp
CREATE TABLE IF NOT EXISTS emp ( eid int, name String,
salary String, destination String)
COMMENT 'Employee details'
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ' '
LINES TERMINATED BY '\n'
STORED AS TEXTFILE;
文件
1201 Gopal 45000 Technicalmanager
1202 Manisha 45000 Proofreader
1203 Masthanvali 40000 Technicalwriter
1204 Kiran 40000 HrAdmin
1205 Kranthi 30000 OpAdmin
3) 導入數據到hive數據倉庫
LOAD DATA LOCAL INPATH '/home/hdfs/emp.txt' OVERWRITE INTO TABLE emp;
4) 插入數據,
insert into emp values(1333,4321,432,4321);
5) hive默認不支持數據的update和delete,要想支持行級insert、update、delete,需要配置Hive支持事務。
1.9 java連接hive
創建maven工程,pom配置如下:
關鍵代碼:
//通用查詢方法
public List
conn=getConnection();//獲取連接
List
try {
ps=conn.prepareStatement(sql);
ps=setParam(ps, params);
rs=ps.executeQuery();//執行查詢,並返回結果集
ResultSetMetaData rsmd=rs.getMetaData();//獲取所有的列數
while(rs.next()){//循環遍歷結果集
Map
for (int i = 0; i < rsmd.getColumnCount(); i++) {
//獲取列名並轉小寫
map.put(rsmd.getColumnName(i+1).toLowerCase(), rs.getObject(i+1));
}
objList.add(map);//封裝每一行數據
}
} catch (SQLException e) {
e.printStackTrace();
}finally{
closeConnection(conn, ps, rs);
}
return objList;
}
/**
* @param args
*/
public static void main(String[] args) {
HiveDao bd = new HiveDao();
List
for (Map
System.out.println(map);
}
}
}
閱讀更多 HelloTeacher陳 的文章