Hive是由Facebook開發的構建在Hadoop之上的數據倉庫平臺。
它自己並不存儲和處理數據,依賴於HDFS存儲數據,依賴MR處理數據。而hive提供了一個相似sql的查詢語言HiveQL來進行查詢、變換數據等操做。固然HiveQL語句的底層是轉換爲相應的mapreduce代碼進行執行,通常採用批處理的方式對海量數據進行處理。
設計目標就是將hadoop上的數據能夠執行SQL操做。
讓熟悉SQL編程的開發人員可以輕鬆的向Hadoop平臺上轉移。
數據倉庫存儲的是靜態數據,很適合採用MR進行批處理。Hive還提供了一系列對數據進行提取、轉換、加載的工具,能夠存儲、查詢和分析存儲在HDFS上的數據。html
是分佈式的關係型數據庫。主要用來並行分佈式處理大量數據。hive中的全部查詢除了select * from table;
都是須要經過MapReduce的方式來執行的。
因爲要走MapReduce(8088mr監控端口號),即便一個只有1行1列的表,若是不是經過select * from table;方式來查詢的,可能也須要八、9秒。
但hive比較擅長處理大量數據。當要處理的數據不少,而且Hadoop集羣有足夠的規模,這時就能體現出它的優點。mysql
一、查詢語言
因爲 SQL 被普遍的應用在數據倉庫中,所以,專門針對 Hive 的特性設計了類 SQL 的查詢語言 HQL。熟悉 SQL 開發的開發者能夠很方便的使用 Hive 進行開發。
二、數據存儲位置
hive的數據都是存儲在 HDFS 中的。而mysql數據庫則能夠將數據保存在本地文件系統中。
三、數據格式
hive 中沒有定義專門的數據格式,數據格式能夠由用戶指定,用戶定義數據格式須要指定三個屬性:列分隔符(一般爲空格、」t」、」x001″)、行分隔符(」n」)以及讀取文件數據的方法(Hive 中默認有三個文件格式 TextFile,SequenceFile 以及 RCFile)。因爲在加載數據的過程當中,不須要從用戶數據格式到 Hive 定義的數據格式的轉換,所以,Hive 在加載的過程當中不會對數據自己進行任何修改,而只是將數據內容複製或者移動到相應的 HDFS 目錄中。
而在數據庫中,不一樣的數據庫有不一樣的存儲引擎,定義了本身的數據格式。全部數據都會按照必定的組織存儲,所以,數據庫加載數據的過程會比較耗時。
四、數據更新
因爲 hive 是針對數據倉庫應用設計的,而數據倉庫的內容是讀多寫少的。所以,hive 中不支持對數據的改寫(hive(0.14) 後支持)和添加
,全部的數據都是在加載的時候中肯定好的。而數據庫中的數據一般是須要常常進行修改的,所以能夠添加、修改數據。sql
五、索引
由於hive 在加載數據的過程當中不會對數據進行任何處理,甚至不會對數據進行掃描,所以也沒有對數據中的某些 Key 創建索引。hive 要訪問數據中知足條件的特定值時,須要暴力掃描整個數據,所以訪問延遲較高。
不過因爲 MapReduce 的引入,hive 能夠並行訪問數據,所以即便沒有索引,對於大數據量的訪問,hive 仍然能夠體現出優點。
數據庫中,一般會針對一個或者幾個列創建索引,所以對於少許的特定條件的數據的訪問,數據庫能夠有很高的效率,較低的延遲。因爲數據的訪問延遲較高,決定了 hive 不適合在線數據查詢
。shell
六、執行
hive 中大多數查詢的執行是經過 Hadoop 提供的 MapReduce 來實現的(相似 select * from tbl 的查詢不須要 MapReduce)。
而數據庫一般有本身的執行引擎。數據庫
七、執行延遲
以前提到hive 在查詢數據的時候,因爲沒有索引,須要掃描整個表,所以延遲較高。另外 一個致使 hive 執行延遲高的因素是 MapReduce 框架。因爲 MapReduce 自己具備較高的延遲,所以在利用 MapReduce 執行 hive 查詢時,也會有較高的延遲。
相對的,數據庫的執行延遲較低。固然,這個低是有條件的,即數據規模較小,當數據規模大到超過數據庫的處理能力的時候,hive 的並行計算顯然能體現出優點。編程
八、可擴展性
因爲 hive 是創建在 Hadoop 之上的,所以 Hive 的可擴展性是和 Hadoop 的可擴展性是 一致的。
而數據庫因爲 ACID 語義的嚴格限制,擴展行很是有限。目前最早進的並行數據庫 Oracle 在理論上的擴展能力也只有 100 臺左右。數組
九、數據規模
因爲 Hive 創建在集羣上並能夠利用 MapReduce 進行並行計算,所以能夠支持很大規模的數據.
數據庫能夠支持的數據規模較小。網絡
數據庫是面向事務的設計,數據倉庫是面向主題設計的。
數據庫通常存儲在線交易數據,數據倉庫存儲的通常是歷史數據。
數據庫設計是儘可能避免冗餘,通常採用符合範式的規則來設計,數據倉庫在設計是有意引入冗餘,採用反範式的方式來設計。
數據庫是爲捕獲數據而設計,數據倉庫是爲分析數據、用於支持管理決策而設計,它的兩個基本的元素是維表和事實表。(維是看問題的角度,好比時間,部門,維表放的就是這些東西的定義,事實表裏放着要查詢的數據,同時有維的ID)app
一、hive是分佈式的關係型數據庫,而hbase是分佈式的非關係型的。
二、hive是面向行存儲的數據庫,而hbase是面向列的數據庫。
三、hive支持類sql語言,經過數據庫的方式來操做hdfs文件系統,爲了簡化編程,底層計算方式爲mapreduce。而hbase的Shell命令是以JRuby爲核心編寫的,不支持sql。
四、hive自己不存儲和計算數據,它徹底依賴於HDFS和MapReduce,hive中的表純邏輯;而hbase是爲查詢而生的,它經過組織起節點內全部機器的內存,提供一個超大的內存Hash表,是物理表。
五、hive是高延遲、結構化和麪向分析的經常使用於離線分析業務,hbase是低延遲、非結構化和麪向編程的,經常使用於在線業務。
6.hive能夠認爲是map-reduce的一個包裝。hive的意義就是把好寫的hive的sql轉換爲複雜難寫的map-reduce程序。而hbase能夠認爲是hdfs的一個包裝。他的本質是數據存儲,是個NoSql數據庫;hbase部署於hdfs之上,而且克服了hdfs在隨機讀寫方面的缺點。框架
含CLI、client、WebUI、JDBC、Thrift Server等,用來實現對Hive的訪問。
CLI是Hive自帶的命令行界面hive shell;WebUI是Hive的一個簡單網頁界面經過hive --server hwi
啓動後,查看9999端口;JDBC、ODBC以及Thrift Server可向用戶提供進行編程的接口,其中Thrift Server是基於Thrift軟件框架開發的,提供Hive的RPC通訊接口。
是一個獨立的關係型數據庫,一般與MySQL數據庫鏈接後建立的一個MySQL實例,也能夠是Hive自帶的Derby數據庫實例。此模塊主要保存表模式和其餘系統元數據,如表的名稱、表的列及其屬性、表的分區及其屬性、表的屬性、表中數據所在位置信息等。
含解析器、編譯器、優化器、執行器等,負責把HiveQL語句轉換成一系列MR做業,全部命令和查詢都會進入驅動模塊,經過該模塊的解析變異,對計算過程進行優化,而後按照指定的步驟執行。
解析器:將sql字符串轉換成抽象語法樹AST,通常用第三方工具庫如antlr完成。而後對AST進行語法分析,如表是否存在、字段是否存在、sql語義是否有誤。
編譯器:將AST編譯生成邏輯執行計劃。
優化器:多邏輯執行計劃進行優化;
執行器:把邏輯執行計劃轉換成能夠運行的物理計劃,即mapreduce/spark/tez。
有些查詢不會走mapreduce,如select * from tbl
http://sishuok.com/forum/blog...
HQL支持基本類型和複雜類型兩大類數據類型。
基本類型包括TINYINT(1byte), SMALLINT(2byte), INT(4byte), BIGINT(8byte), FLOAT(4byte), DOUBLE(8byte),DECIMAL(32精度) BOOLEAN(-), STRING(2G)。
複雜類型包括ARRAY(一組有序數組,類型必須一致), MAP(無序鍵值對,鍵值內部字段類型必須相同,並且要求key的類型爲基本數據類型), STRUCT(一組字段,類型任意)如<a:STRING,B:INT,C:DOUBLE>。
注意是指hql中使用的數據形式,而不是表中序列化存儲的格式。
hive 中的文件格式有:
SEQUENCEFILE TEXTFILE -- (Default, depending on hive.default.fileformat configuration) RCFILE -- (Note: Available in Hive 0.6.0 and later) ORC -- (Note: Available in Hive 0.11.0 and later) PARQUET -- (Note: Available in Hive 0.13.0 and later) AVRO -- (Note: Available in Hive 0.14.0 and later) INPUTFORMAT input_format_classname OUTPUTFORMAT output_format_classname
還能夠自定經過InputFormat、OutputFormat
採用RCfile的格式讀取的數據量(373.94MB)遠遠小於sequenceFile的讀取量(2.59GB)
執行速度前者(68秒)比後者(194秒)快不少。
壓縮比:bzip2>gzip>lzo
解壓速度:lzo>gzip>bzip2
snappy的執行進度遠遠高於bz的執行進度。
在hive中使用壓縮須要靈活的方式,若是是數據源的話,採用RCFile+bz或RCFile+gz的方式,這樣能夠很大程度上節省磁盤空間;
而在計算的過程當中,爲了避免影響執行的速度,能夠浪費一點磁盤空間,建議採用RCFile+snappy的方式,這樣能夠總體提高hive的執行速度。
至於lzo的方式,也能夠在計算過程當中使用,只不過綜合考慮(速度和壓縮比)仍是考慮snappy適宜。
默認存儲在/user/hive/warehouse下,也能夠經過location指定,但通常不會指定。
內部表是hive進行管理的,刪除表時,會刪除表數據以及元數據。
外部表在建立表時能夠本身指定目錄位置(LOCATION),通常會指定(目錄要求先存在)。通常狀況下,咱們在建立外部表的時候會將表數據的存儲路徑定義在hive的數據倉庫路徑以外。
外部表的數據不是有hive進行管理的,刪除表時,只會刪除元數據不會刪除表數據。
供多個部門使用(包括刪除)。
主要做用是查看database、table、function等組件的名稱信息,也就是經過show命令咱們能夠知道咱們的hive中有那些database;當前database中有那些table。等等。和mysql的show命令類型。show databases ;
數據庫show databases like 'db_hive*' ;
show tables ;
show create table 表名;
獲得建立該表的語句show partitions 表名 ;
查看錶中有多少分區
show functions ;
查看自帶函數
主要做用是獲取database、table、partition的具體描述信息,包括存儲位置、字段類型等信息。desc database db_hive_03 ;
desc database extended db_hive_03 ;
desc student ;
看錶結構desc extended student ;
看錶完整信息,但比較亂desc formatted student ;
看格式化的信息,經常使用
desc function upper ;
看函數upper的使用說明desc function extended upper ;
看函數的案例演示select id ,upper(name) uname from db_hive.student ;
create database db_hive_01 ;
create database if not exists db_hive_02 ;
標準create database if not exists db_hive_03 location '/user/cyan/hive/warehouse/db_hive_03.db' ;
默認是/user/hive/,沒有會自動建立
use db_hive;
當前使用數據庫,不然用數據庫名.表名
簡單如:create table student(id int, name string) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';
製表符分隔各行數據。
複雜一點:
create table IF NOT EXISTS default.log_20150913( ip string COMMENT 'remote ip address' , user string , req_url string COMMENT 'user request url') COMMENT 'BeiFeng Web Access Logs' ROW FORMAT DELIMITED FIELDS TERMINATED BY ' ' STORED AS TEXTFILE ;//以文本文件形式保存,列中的分隔符是空格,行中的分隔符回車 [ROW FORMAT row_format], row_format格式: delimited fields terminated by '\001' collection terminated by '\002' map keys terminated by '\003' lines terminated by '\004' NULL DEFINED AS '\N' [STORED AS file_format] file_format格式: sequencefile textfile(default) rcfile orc parquet avro
create table IF NOT EXISTS default.log_20150913_sa AS select ip,req_url from default.log_20150913 ;
AS sselect來自另一張表(分表),利用其餘表的格式like:create table if not exists default.dept_like like default.dept ;
eg:建立員工表
create table IF NOT EXISTS default.emp( empno int, ename string, job string, mgr int,上級 hiredate string,入職時間 sal double, comm double,獎金 deptno int部門 ) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';
eg:建立部門表
create table IF NOT EXISTS default.dept( deptno int, dname string, loc string ) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';
有時候想把數據細部劃分,分各個目錄,好比日誌文件:
/user/hive/warehouse/log/ /20150911/ 20150911.log /20150912/ 20150912.log
此時建立表時可用partitioned by指定分區依據:
create EXTERNAL table IF NOT EXISTS default.emp_partition( empno int, ename string, job string, mgr int, hiredate string, sal double, comm double, deptno int ) partitioned by (month string,day string) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' ;
往分區表導入數據時,須要指定肯定分區的字段值:load data local inpath '/opt/datas/emp.txt' into table default.emp_partition partition (month='201509',day='13') ;
若是建表時指定了數據位置,即加了location '/user/cyan/hive/warehouse/emp_partition';
,則直接把txt數據上傳至hdfs的該目錄中便可。
從分區表查詢數據,也須要指定肯定分區的字段值:select * from emp_partition where month = '201509' and day = '13' ;
除了使用patitioned,還能夠手動在表的hdfs目錄下建立分區目錄達到建分區表的目的:
第一種方式 dfs -mkdir -p /user/hive/warehouse/dept_part/day=20150913 ; dfs -put /opt/datas/dept.txt /user/hive/warehouse/dept_part/day=20150913 ; hive (default)> msck repair table dept_part ;修復後,才能select出數據 第二種方式 dfs -mkdir -p /user/hive/warehouse/dept_part/day=20150914 ; dfs -put /opt/datas/dept.txt /user/hive/warehouse/dept_part/day=20150914 ; alter table dept_part add partition(day='20150914'); show partitions dept_part ; 查看錶中有多少分區
LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE tablename [PARTITION (partcol1=val1, partcol2=val2 ...)];
local 本地數據,不加則是hdfs數據
partition (partcol1=val1,...)分區表加載,特殊性,詳見分區表的建立。
eg:load data local inpath '/opt/datas/student.txt'into table student ;
加載數據 utf-8格式load data local inpath '/opt/datas/student1.txt' overwrite into table student ;
覆蓋原數據,默認是追加
create table default.emp_ci like emp ;
insert into table default.emp_ci select * from default.emp ;
insert overwrite local directory '/opt/datas/hive_exp_emp' select * from default.emp ;
導出數據到本地insert overwrite directory '/user/beifeng/hive/hive_exp_emp' select * from default.emp ;
導出數據到hdfs
insert overwrite local directory '/opt/datas/hive_exp_emp2' ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' COLLECTION ITEMS TERMINATED BY '\n' select * from default.emp ;
建立表的時候經過location指定加載數據
CREATE [TEMPORARY] [EXTERNAL] TABLE [IF NOT EXISTS] [db_name.]table_name LIKE existing_table_or_view_name [LOCATION hdfs_path];
將外部數據導入hive表中
create table db_hive.emp like default.emp ; import table db_hive.emp from '/user/beifeng/hive/export/emp_exp';
EXPORT TABLE default.emp TO '/user/beifeng/hive/export/emp_exp' ;
將Hive表中的數據,導出到外部(HDFS)
1.hive shellbin/hive -e "select * from default.emp ;" > /opt/datas/exp_res.txt
2.sqoop
alter table dept_like rename to dept_like_rename ;
改表名
也能夠加列名
drop database if exists db_hive_03 ;
非空就不能刪drop database db_hive_03 cascade;
非空能刪,目錄也被刪了drop database if exists db_hive_03 ;
清除表裏的數據:truncate table db_hive_03 ;
select * from student ;
沒有走mapreduceselect id from student ;
走MR
官網LanguageManual中:
[WITH CommonTableExpression (, CommonTableExpression)*] SELECT [ALL | DISTINCT] select_expr, select_expr, ... FROM table_reference [WHERE where_condition] [GROUP BY col_list] [CLUSTER BY col_list | [DISTRIBUTE BY col_list] [SORT BY col_list] ] [LIMIT number] select * from emp where GROUP BY LIMIT number
from語句主要是指定從那個數據表中查詢數據,有兩種使用方式:分別能夠在select後和with後&select前使用,語法格式:
[with ...] select ... from ...
[with ...] from ... select ...
示例:select * from students;
from students select *;
hive對子查詢的支持有限,只支持嵌套select子句,並且只能在from和with語句塊中使用子查詢。語法規則以下:.... from (select statement) [[as] tmp_name]....
select * from emp limit 5 ;
select t.empno, t.ename, t.deptno from emp t where t.sal between 800 and 1500 ;
select t.empno, t.ename, t.deptno from emp t where comm is null ;
select count(*) cnt from emp ;
select max(sal) max_sal from emp ;
select sum(sal) from emp ;
select avg(sal) from emp ;
eg:每一個部門的平均工資select t.deptno, avg(t.sal) avg_sal from emp t group by t.deptno ;
eg:每一個部門中每一個崗位的最高薪水select t.deptno, t.job, max(t.sal) avg_sal from emp t group by t.deptno, job ;
eg:每一個部門的平均薪水大於2000的部門select deptno, avg(sal) avg_sal from emp group by deptno having avg_sal > 2000;
=======================================
目前hive不支持in
或not in
中包含查詢子句的語法,因此只能經過left join實現。
1.等值jion
join ... onselect e.empno, e.ename, d.deptno, d.dname from emp e join dept d on e.deptno = d.deptno ;
不支持<>等非等值鏈接方式。
2.左鏈接
left joinselect e.empno, e.ename, d.deptno, d.dname from emp e left join dept d on e.deptno = d.deptno ;
3.右鏈接
right joinselect e.empno, e.ename, e.deptno, d.dname from emp e right join dept d on e.deptno = d.deptno ;
4.全鏈接
full joinselect e.empno, e.ename, e.deptno, d.dname from emp e full join dept d on e.deptno = d.deptno ;
5.半鏈接(LEFT SEMI JOIN)
是hive特有的,hive中不支持in/exists操做,因此hive提供了一個替代方案。須要注意的是,被鏈接的表(右表),不能出如今查詢列/其餘部分(where等)中,只能出如今on字句中(出現也是無效的)。
提出半鏈接的主要做用實際上是提升查詢效率,真正來說的話,hive中可使用其餘鏈接方式來代替半鏈接,可是就效率而已的話,仍是半鏈接比較高效。
語法格式:table_reference LEFT SEMI JOIN table_factor join_condition;
6.多表鏈接
多表鏈接的時候,通常先進行left semi join,而後再進行join, 再進行外鏈接。(減小數據量)。
補充:
join過濾條件,能夠將where的過濾條件移動到join的過濾條件中去,這樣能夠減小網絡數據量。
join執行順序都是從左到右,無論是那種join方式,那麼通常將大的表放到右邊
,這樣能夠節省內存&減小網絡傳輸。
若是全部被鏈接的表都是小表,那麼可使用mapjoin,將須要鏈接的表數據所有讀入mapper端內存中。也就是說你使用mapjoin的前提就是你的鏈接數據比較小,mapjoin須要和其餘join方式一塊兒使用,通常狀況下使用mapjoin的時候,推薦使用內鏈接。語法格式爲:select /*+ MAPJOIN(table_ref1) */ ... from table_ref join table_ref1 on ....;
mapjoin只適合鏈接表是小表的狀況,是一種空間換時間的解決方案。
對全局數據的一個排序,僅僅只有1個reduceselect * from emp order by empno desc ;
降序
對每個reduce內部數據進行排序的,全局結果集來講不是排序
`set mapreduce.job.reduces= 3;
select * from emp sort by empno asc ;
insert overwrite local directory '/opt/datas/sortby-res' select * from emp sort by empno asc ;`
分區partition,相似於MapReduce中分區partition,對數據進行分區,結合sort by進行使用(分區再排序)insert overwrite local directory '/opt/datas/distby-res' select * from emp distribute by deptno sort by empno asc ;
注意事項:distribute by
必需要在sort by
前面。
當distribute by和sort by 字段相同時,可使用cluster by ;insert overwrite local directory '/opt/datas/cluster-res' select * from emp cluster by empno ;
1.應儘可能避免在where 子句中對字段進行null 值判斷,不然將致使引擎放棄使用索引而進行全表掃描
2.應儘可能避免在 where 子句中使用!=或<>操做符,不然將引擎放棄使用索引而進行全表掃
3.描應儘可能避免在 where 子句中使用or 來鏈接條件,不然將致使引擎放棄使用索引而進行全表掃描
4.in 和 not in,用具體的字段列表代替,不要返回用不到的任何字段。in 也要慎用,不然會致使全表掃描
5.避免使用模糊查詢
6.任何地方都不要使用select* from t;
dfs -rm -R /user/hive/warehouse/….;
刪除dfs -ls / ;
查看hdfs文件系統!ls /opt/datas ;
查看本地文件系統