hive梳理

what's

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

與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

與hbase比較

一、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通訊接口。

元數據存儲模塊(Metastore)

是一個獨立的關係型數據庫,一般與MySQL數據庫鏈接後建立的一個MySQL實例,也能夠是Hive自帶的Derby數據庫實例。此模塊主要保存表模式和其餘系統元數據,如表的名稱、表的列及其屬性、表的分區及其屬性、表的屬性、表中數據所在位置信息等。

驅動模塊(Driver)

含解析器、編譯器、優化器、執行器等,負責把HiveQL語句轉換成一系列MR做業,全部命令和查詢都會進入驅動模塊,經過該模塊的解析變異,對計算過程進行優化,而後按照指定的步驟執行。
解析器:將sql字符串轉換成抽象語法樹AST,通常用第三方工具庫如antlr完成。而後對AST進行語法分析,如表是否存在、字段是否存在、sql語義是否有誤。
編譯器:將AST編譯生成邏輯執行計劃。
優化器:多邏輯執行計劃進行優化;
執行器:把邏輯執行計劃轉換成能夠運行的物理計劃,即mapreduce/spark/tez。

有些查詢不會走mapreduce,如select * from tbl

安裝配置

http://sishuok.com/forum/blog...

hive數據

數據類型

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進行管理的,刪除表時,只會刪除元數據不會刪除表數據。
供多個部門使用(包括刪除)。

hive Cli

show

主要做用是查看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 ;查看自帶函數

describe

主要做用是獲取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

建立數據庫

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';

建立分區表partitioned by

有時候想把數據細部劃分,分各個目錄,好比日誌文件:

/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

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 ;覆蓋原數據,默認是追加

insert

建立表時經過insert加載數據

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

建立表的時候經過location指定加載數據

CREATE [TEMPORARY] [EXTERNAL] TABLE [IF NOT EXISTS] [db_name.]table_name
  LIKE existing_table_or_view_name
  [LOCATION hdfs_path];

import

將外部數據導入hive表中

create table db_hive.emp like default.emp ;
import table db_hive.emp from '/user/beifeng/hive/export/emp_exp';

export

EXPORT TABLE default.emp TO '/user/beifeng/hive/export/emp_exp' ;將Hive表中的數據,導出到外部(HDFS)

其餘導出數據方式

1.hive shell
bin/hive -e "select * from default.emp ;" > /opt/datas/exp_res.txt

2.sqoop

alter

alter table dept_like rename to dept_like_rename ;改表名
也能夠加列名

drop

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

select * from student ;沒有走mapreduce
select 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前使用,語法格式:

  1. [with ...] select ... from ...
  2. [with ...] from ... select ...

示例:
select * from students;
from students select *;

子查詢

hive對子查詢的支持有限,只支持嵌套select子句,並且只能在from和with語句塊中使用子查詢。語法規則以下:
.... from (select statement) [[as] tmp_name]....

limit、= >= <= between and

select * from emp limit 5 ;
select t.empno, t.ename, t.deptno from emp t where t.sal between 800 and 1500 ;

is null / is not null /in /not in

select t.empno, t.ename, t.deptno from emp t where comm is null ;

max/min/count/sum/avg

select count(*) cnt from emp ;
select max(sal) max_sal from emp ;
select sum(sal) from emp ;
select avg(sal) from emp ;

group by

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 ;

having

eg:每一個部門的平均薪水大於2000的部門
select deptno, avg(sal) avg_sal from emp group by deptno having avg_sal > 2000;

=======================================

join

目前hive不支持innot in 中包含查詢子句的語法,因此只能經過left join實現。
1.等值jion
join ... on
select e.empno, e.ename, d.deptno, d.dname from emp e join dept d on e.deptno = d.deptno ;
不支持<>等非等值鏈接方式。

2.左鏈接
left join
select e.empno, e.ename, d.deptno, d.dname from emp e left join dept d on e.deptno = d.deptno ;

3.右鏈接
right join
select e.empno, e.ename, e.deptno, d.dname from emp e right join dept d on e.deptno = d.deptno ;

4.全鏈接
full join
select 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只適合鏈接表是小表的狀況,是一種空間換時間的解決方案。

order by

對全局數據的一個排序,僅僅只有1個reduce
select * from emp order by empno desc ;降序

sort by

對每個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 ;`

distribute by

分區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 前面。

cluster 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 ;查看本地文件系統

HQL語句轉換成MapReduce做業的基本原理

https://blog.csdn.net/nameles...

相關文章
相關標籤/搜索