HADOOP:HIVE常用知識總結


HIVE簡介

hive (數據倉庫工具):hive是基於Hadoop的一個數據倉庫工具,可以將結構化的數據文件映射爲一張數據庫表,並提供簡單的sql查詢功能,可以將sql語句轉換爲MapReduce任務進行運行。 其優點是學習成本低,可以通過類SQL語句快速實現簡單的MapReduce統計,不必開發專門的MapReduce應用,十分適合數據倉庫的統計分析。Hive 沒有專門的數據格式。 Hive 可以很好的工作在 Thrift 之上,控制分隔符,也允許用戶指定數據格式。

:thrift是一個軟件框架,用來進行可擴展且跨語言的服務的開發。它結合了功能強大的軟件堆棧和代碼生成引擎,以構建在 C++, Java, Go,Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript, Node.js, Smalltalk, and OCaml 這些編程語言間無縫結合的、高效的服務。


適用場景

Hive 構建在基於靜態批處理的Hadoop 之上,Hadoop 通常都有較高的延遲並且在作業提交和調度的時候需要大量的開銷。因此,Hive 並不能夠在大規模數據集上實現低延遲快速的查詢,例如,Hive 在幾百MB 的數據集上執行查詢一般有分鐘級的時間延遲。因此,Hive 並不適合那些需要低延遲的應用,例如,聯機事務處理(OLTP)。Hive 查詢操作過程嚴格遵守Hadoop MapReduce 的作業執行模型,Hive 將用戶的HiveQL 語句通過解釋器轉換爲MapReduce 作業提交到Hadoop 集羣上,Hadoop 監控作業執行過程,然後返回作業執行結果給用戶。Hive 並非爲聯機事務處理而設計,Hive 並不提供實時的查詢和基於行級的數據更新操作。Hive 的最佳使用場合是大數據集的批處理作業,例如,網絡日誌分析。


基礎操作

hive --help  //幫助信息   

變量和屬性:–define key=value 實際上和 –hivevar key=value 是等價的
這裏寫圖片描述

在CLI中,可以使用set命令替換顯示或者修改變量值。

set env:HOME    //顯示變量
--define foo=bar  //定義
set foo     //顯示變量
foo=bar     //output

set hivevar:foo
hivevar:foo=bar     //輸出信息

set hivevar:foo=bar2
set hivevar:foo
hivevar:foo=bar2        //輸出信息

describe k_table        //顯示錶的信息

hive -e "select * from k_test"      //一次性執行語句,執行完就退出  -e
hive -S .....       //-S開啓靜默模式
hive -f /path/to/file/xxx.hql  //開啓 -f 執行指定文件中的語句
source /path/to/file/xxx.hql        //在hive中用source命令來執行腳本
//hive啓動的時候會首先執行用戶目錄下的.hiverc 文件,比如說在.hiverc增加一些參數設置,增加jar包等操作
!echo "Hello hive"      //hive在不退出的情況下就可以執行linux 命令,在前面加上 !
dfs -ls ~~~      //在hive中執行dfs命令
--      //hive腳本進行註釋的方式

數據類型和文件格式

基本數據類型

這裏寫圖片描述
這裏寫圖片描述


複合數據類型

這裏寫圖片描述

:: 注::

Struct 內可以聲明爲不同類型的字段
Array 內必須是同種類型的
Map 即字典 ,key.value操作

創建一個employee表

create table employee(
name    STRING,
salary  FLOAT,
subord  ARRAY<STRING>,
ded     MAP<STRING,FLOAT>,
address STRUCT<street:STRING,city:STRING,zip:INT>
)

文本文件數據編碼

hive 使用術語 field來替換默認分隔符的字符
這裏寫圖片描述

例如,創建一個表,定義表數據按照逗號分隔

create table employee(
name    STRING,
salary  FLOAT,
subord  ARRAY<STRING>,
ded     MAP<STRING,FLOAT>,
address STRUCT<street:STRING,city:STRING,zip:INT>
)
row format delimited fields terminated by ',';  -- \t 爲製表鍵

hive文件存儲格式包括以下幾類:

1、TEXTFILE
2、SEQUENCEFILE
3、RCFILE
4、ORCFILE(0.11以後出現)

其中TEXTFILE爲默認格式,建表時不指定默認爲這個格式,導入數據時會直接把數據文件拷貝到hdfs上不進行處理;SEQUENCEFILE,RCFILE,ORCFILE格式的表不能直接從本地文件導入數據,數據要先導入到textfile格式的表中, 然後再從表中用insert導入SequenceFile,RCFile,ORCFile表中。

一、TEXTFILE
默認格式,數據不做壓縮,磁盤開銷大,數據解析開銷大。
可結合Gzip、Bzip2使用(系統自動檢查,執行查詢時自動解壓),但使用這種方式,hive不會對數據進行切分,
從而無法對數據進行並行操作。
舉例:

//創建一張testfile_table表,格式爲textfile。

create table if not exists testfile_table( 
site string, url  string, pv   bigint, label string
) 
row format delimited fields terminated by '\t' stored as textfile;  --stored 關鍵字指定格式

load data local inpath '/app/weibo.txt' overwrite into table textfile_table;

--插入數據操作:
set hive.exec.compress.output=true;  --指定壓縮
set mapred.output.compress=true;  --指定壓縮
set mapred.output.compression.codec=org.apache.hadoop.io.compress.GzipCodec;  --指定壓縮
set io.compression.codecs=org.apache.hadoop.io.compress.GzipCodec;  --指定壓縮
insert overwrite table textfile_table select * from textfile_table;  --插入數據

二、SEQUENCEFILE
SequenceFile是Hadoop API提供的一種二進制文件支持,其具有使用方便、可分割、可壓縮的特點。
SequenceFile支持三種壓縮選擇:NONE,RECORD,BLOCK。Record壓縮率低,一般建議使用BLOCK壓縮。
示例:

create table if not exists seqfile_table(
site string,
url  string,
pv   bigint,
label string
)
row format delimited
fields terminated by '\t'
stored as sequencefile;

插入數據操作:
set hive.exec.compress.output=true;  
set mapred.output.compress=true;  
set mapred.output.compression.codec=org.apache.hadoop.io.compress.GzipCodec;  
set io.compression.codecs=org.apache.hadoop.io.compress.GzipCodec;  
SET mapred.output.compression.type=BLOCK;   --指定壓縮選擇
insert overwrite table seqfile_table select * from textfile_table;

三、RCFILE
RCFILE是一種行列存儲相結合的存儲方式。首先,其將數據按行分塊,保證同一個record在一個塊上,避免讀一個記錄需要讀取多個block。其次,塊數據列式存儲,有利於數據壓縮和快速的列存取。
RCFILE文件示例:

create table if not exists rcfile_table(
site string,
url  string,
pv   bigint,
label string
)
row format delimited
fields terminated by '\t'
stored as rcfile;

插入數據操作:
set hive.exec.compress.output=true;  
set mapred.output.compress=true;  
set mapred.output.compression.codec=org.apache.hadoop.io.compress.GzipCodec;  
set io.compression.codecs=org.apache.hadoop.io.compress.GzipCodec;  
insert overwrite table rcfile_table select * from textfile_table;

四、ORCFILE 同樣

五、再看TEXTFILE、SEQUENCEFILE、RCFILE三種文件的存儲情況:

[hadoop@node3 ~]$ hadoop dfs -dus /user/hive/warehouse/*

hdfs://node1:19000/user/hive/warehouse/hbase_table_1    0
hdfs://node1:19000/user/hive/warehouse/hbase_table_2    0
hdfs://node1:19000/user/hive/warehouse/orcfile_table    0
hdfs://node1:19000/user/hive/warehouse/rcfile_table    102638073
hdfs://node1:19000/user/hive/warehouse/seqfile_table   112497695
hdfs://node1:19000/user/hive/warehouse/testfile_table  536799616
hdfs://node1:19000/user/hive/warehouse/textfile_table  107308067


[hadoop@node3 ~]$ hadoop dfs -ls /user/hive/warehouse/*/

-rw-r--r--   2 hadoop supergroup   51328177 2014-03-20 00:42 /user/hive/warehouse/rcfile_table/000000_0
-rw-r--r--   2 hadoop supergroup   51309896 2014-03-20 00:43 /user/hive/warehouse/rcfile_table/000001_0

-rw-r--r--   2 hadoop supergroup   56263711 2014-03-20 01:20 /user/hive/warehouse/seqfile_table/000000_0
-rw-r--r--   2 hadoop supergroup   56233984 2014-03-20 01:21 /user/hive/warehouse/seqfile_table/000001_0

-rw-r--r--   2 hadoop supergroup  536799616 2014-03-19 23:15 /user/hive/warehouse/testfile_table/weibo.txt
-rw-r--r--   2 hadoop supergroup   53659758 2014-03-19 23:24 /user/hive/warehouse/textfile_table/000000_0.gz
-rw-r--r--   2 hadoop supergroup   53648309 2014-03-19 23:26 /user/hive/warehouse/textfile_table/000001_1.gz

總結:相比TEXTFILE和SEQUENCEFILE,RCFILE由於列式存儲方式,數據加載時性能消耗較大,但是具有較好的壓縮比和查詢響應。數據倉庫的特點是一次寫入、多次讀取,因此,整體來看,RCFILE相比其餘兩種格式具有較明顯的優勢


數據定義

數據庫常用操作

//查看所有的數據庫
hive> show databases ;

//使用數據庫default
hive> use default;

//查看數據庫信息
hive > describe database default; 
OK 
db_name comment location owner_name owner_type parameters 
default Default Hive database hdfs://hadoop1:8020/user/hive/warehouse public ROLE 
Time taken: 0.042 seconds, Fetched: 1 row(s)

//顯示地展示當前使用的數據庫
hive> set hive.cli.print.current.db=true; 
hive(default)>

//創建數據庫命令
hive (default)> create database test comment "描述信息"; 
OK 
Time taken: 10.128 seconds

//切換當前的數據庫
hive (default)> use test; 
OK 
Time taken: 0.031 seconds 
hive (test)>

//刪除數據庫
刪除數據庫的時候,不允許刪除有數據的數據庫,如果數據庫裏面有數據則會報錯。如果要忽略這些內容,則在後面增加CASCADE關鍵字,則忽略報錯,刪除數據庫。

hive> DROP DATABASE DbName CASCADE(可選); 
hive> DROP DATABASE IF EXISTS DbName CASCADE;

//修改數據庫
alter database test set ....

數據表常用操作

//查看當前DB有啥表
hive> SHOW TABLES IN DbName; 
hive> SHOW TABLES IN liguodong; 
OK 
tab_name 
Time taken: 0.165 seconds

//也可以使用正則表達式 hive> SHOW TABLES LIKE 'h*';
hive (default)> SHOW TABLES LIKE '*all*' ;
OK
tab_name
addressall_2015_07_09
Time taken: 0.039 seconds, Fetched: 1 row(s)

//獲得表的建表語句
hive (default)> show create table address1_2015_07_09;
OK
createtab_stmt
CREATE  TABLE `address1_2015_07_09`(
  `addr1` bigint)
ROW FORMAT SERDE
  'org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe'
STORED AS INPUTFORMAT
  'org.apache.hadoop.mapred.TextInputFormat'
OUTPUTFORMAT
  'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
LOCATION
  'hdfs://nameservice1/user/hive/warehouse/address1_2015_07_09'
TBLPROPERTIES (
  'COLUMN_STATS_ACCURATE'='true',
  'numFiles'='1',
  'numRows'='0',
  'rawDataSize'='0',
  'totalSize'='4',
  'transient_lastDdlTime'='1436408451')
Time taken: 0.11 seconds, Fetched: 17 row(s)


//創建表
CREATE [TEMPORARY] [EXTERNAL] TABLE [IF NOT EXISTS] [db_name.]table_name    -- (Note: TEMPORARY available in Hive 0.14.0 and later)
  [(col_name data_type [COMMENT col_comment], ...)]
  [COMMENT table_comment]
  [PARTITIONED BY (col_name data_type [COMMENT col_comment], ...)]   --分區
  [CLUSTERED BY (col_name, col_name, ...) [SORTED BY (col_name [ASC|DESC], ...)] INTO num_buckets BUCKETS]
  [SKEWED BY (col_name, col_name, ...)                  -- (Note: Available in Hive 0.10.0 and later)]
     ON ((col_value, col_value, ...), (col_value, col_value, ...), ...)
     [STORED AS DIRECTORIES]
  [
   [ROW FORMAT row_format] 
   [STORED AS file_format]
     | STORED BY 'storage.handler.class.name' [WITH SERDEPROPERTIES (...)]  -- (Note: Available in Hive 0.6.0 and later)
  ]
  [LOCATION hdfs_path]
  [TBLPROPERTIES (property_name=property_value, ...)]   -- (Note: Available in Hive 0.6.0 and later)
  [AS select_statement];   -- (Note: Available in Hive 0.5.0 and later; not supported for external tables)

//舉個例子
create table employee(
name    STRING,
salary  FLOAT,
subord  ARRAY<STRING>,
ded     MAP<STRING,FLOAT>,
address STRUCT<street:STRING,city:STRING,zip:INT>
)
row format delimited fields terminated by '\t' lines terminated by '\n' stored as textfile; --指定字段分隔符和行分隔符 指定文件存儲格式

//加載數據
hive (default)> load data local inpath ‘/liguodong/hivedata/datatest’ overwrite into table testtable;

hive (default)> load data local inpath ‘/liguodong/hivedata/datatest’ into table testtable;         --如果沒有使用overwrite,則會再拷貝一份數據,不會覆蓋原來的數據。

//查找表數據
--注意:select * 不執行mapreduce,只進行一個本地的查詢。 
--而select 某個字段 生成一個job,執行mapreduce。

select * from employees;
select * from employees limit 10;

//刪除表

--內部表刪除,會連同hdfs存儲的數據一同刪除,而外部表刪除,只會刪除外部表的元數據信息。

hive (default)> drop table testtable;
OK
Time taken: 10.283 seconds
hive (default)> drop table testexttable;
OK
Time taken: 0.258 seconds

//Hive建表的其他方式
--有一個表,創建另一個表(只是複製了表結構,並不會複製內容。) 不需要執行mapreduce
create table test3 like test2; 

--從其他表查詢,再創建表(複製表結構的同時,把內容也複製過來了) 需要執行mapreduce
create table test2 as select name,addr from test1; 

//查看錶的詳細信息
describe formatted/extended  tableName
create EXTERNAL tableName --創建擴展表(外部表)
row format delimited fields terminated by '\t'  --字段分隔符

//創建分區表
create table partitionetest(
name    STRING,
country STRING,
state   STRING
)
partitioned by (country STRING ,state STRING)

這裏寫圖片描述

當用where 來進行分區過濾的時候,這些叫做分區過濾器

set hive.mapred.mode=strict --設置爲嚴格,默認是 nostrict,這樣對分區表進行查詢而where字句沒有分區過濾的話,就會被禁止提交這個任務

查看錶分區信息

show partitions employee;   --查看employee表中的所有分區
show partitions employee(country='US',state='AK');  --查看指定分區的信息

創建一個外部表的分區

create external table if not exists log_message (
hms INT,
severity    STRING,
sever       STRING,
process_id  INT,
message     STRING
)
partitioned by (year int ,month int,day int)
row format delimited fields terminated by '\t';

增加一個表的分區

alter table log_message add if not exists 
partition(year=2012,month=1,day=2)
location 'hdfs://master_sever/data/log_message/2012/01/02'
partition(year=2012,month=1,day=3)
location 'hdfs://master_sever/data/log_message/2012/01/03'
...

修改一個表的分區

alter table log_message partition(year=2012,month=1,day=2)
set location 'hdfs://master_sever/data/log_message/2012/01/02'
--這個命令不會將舊的路徑轉移走,也不會刪除舊的數據

刪除分區

alter table log_message drop if exists partition(year=2012,month=1,day=2)

修改列信息

alter table log_message
change column hms hours_minutes INT
comment 'aaaaaaaaaaaa'  --註釋
after serveri       --移動到serveri之後

增加列信息

alter table log_message add columns (
....        --增加的列信息
....
)

刪除或者替換列

alter table log_message change columns (
....        --修改的列信息
....

數據操作

數據操作能力是大數據分析至關重要的能力。數據操作主要包括:更改(exchange),移動(moving),排序(sorting),轉換(transforming)。Hive提供了諸多查詢語句,關鍵字,操作和方法來進行數據操作。

一、 數據更改 數據更改主要包括:LOAD, INSERT, IMPORT, and EXPORT. 1. LOAD DATA load關鍵字的作用是將數據移動到hive中。如果是從HDFS加載數據,則加載成功後會刪除源數據;如果是從本地加載,則加載成功後不會刪除源數據。

 LOAD DATA LOCAL INPATH '/apps/ca/yanh/employee_hr.txt' 
 OVERWRITE INTO TABLE k_test
 PARTITION (country='US',state='CA'); --裝載數據到k_test表中,PARTITION 可以省略

注1:在指令中LOCAL關鍵字用於指定數據從本地加載,如果去掉該關鍵字,默認從HDFS進行加載! OVERWRITE關鍵字指定使用覆蓋方式進行加載數據,否則使用附加方式進行加載。
注2:如果數據加載到分區表,則必須指定分區列。

INSERT 同RDBMS一樣,Hive也支持從其他hive表提取數據插入到指定表,使用INSERT關鍵字。INSERT操作是Hive數據處理中最常用的將已有數據填充進指定表操作。在Hive中,INSERT可以和OVERWRITE一起使用實現覆蓋插入,可以進行多表插入,動態分區插入以及提取數據至HDFS或本地。

CREATE TABLE ctas_employee AS SELECT * FROM employee; TRUNCATE TABLE employee; --刪除employee中的數據,保留表結構
INSERT INTO TABLE employee SELECT * FROM ctas_employee; --使用INSERT關鍵字

INSERT OVERWRITE TABLE  employees  
PARTITION (country='US',state='CA')
select * from employees_bak re where re.country='US' and re.state='CA';--OVERWRITE 會將之前分區的內容覆蓋掉

//多次插入數據
from stom_employee re
insert OVERWRITE TABLE  employees  
    PARTITION (country='US',state='CA')
    select * from  where re.country='US' and re.state='CA';
insert OVERWRITE TABLE  employees  
    PARTITION (country='US',state='CB')
    select * from  where re.country='US' and re.state='CB';
insert OVERWRITE TABLE  employees  
    PARTITION (country='US',state='CC')
    select * from  where re.country='US' and re.state='CC';

動態分區插入

insert OVERWRITE TABLE  employees  
PARTITION (country='US',state)
select ...,se.coun,se.st
from sta_employee  se
where se.country='US';      --根據state 動態分區插入

導出數據

hadoop fs -cp source_path target_path   --文件格式符合的時候直接複製就可以

INSERT OVERWRITE LOCAL DIRECTORY '/tmp/test/a'
select ...;     --這種方式會將字段序列化成字符串寫入文件中

查詢

select * from tableName r where r....;  --這裏查詢和sql類似,符號 函數,limit 別名 嵌套等方面。

select name,salary
    case
        when salary < 5000 then ...
        when salary > 5000 then ...
    END AS BRUCKET FROM employee;

JOIN:hive只支持等值連接。
**類型轉換:**case()

數據排序 數據排序主要包括:ORDER, and SORT. 該操作同樣經常使用,以便生成已排序表從而進行後面的包括top N, maximum, minimum等取值操作。 主要操作包括ORDER BY (ASC|DESC)、SORT BY(ASC|DESC)、DISTRIBUTE BY、CLUSTER BY

DISTRIBUTE BY :該操作類似於RDBMS中的GROUP BY,根據制定的列將mapper的輸出分組發送至reducer,而不是根據partition來分組數據。 注:如果使用了SORT BY,那麼必須在DISTRIBUTE BY之後,且要分發的列必須出現在已選擇的列中(因爲SORT BY的性質)。

CLUSTER BY: CLUSTER BY類似於DISTRIBUTE BY和SORT BY的組合作用(作用於相同列),但不同於ORDER BY的是它僅在每個reducer進行排序,而不是全局排序,且不支持ASC和DESC。如果要實現全局排序,可以先進行CLUSTER BY然後再ORDER BY。


模式設計

  1. 分區,按照年 月 日 或者一些靜態的字段來進行,這樣查詢的時候在where中指定條件的時候就指定這些分區的信息,會優化查詢速度

  2. 分桶技術是將數據集分解成更容易管理的若干部分的另一個技術。例如一級分區是天,二級分區是ID,這樣會由於ID過多導致出現問題,這種情況下,就可以用天作爲分區 ID進行桶操作。

  3. 使用列存儲表

  4. 總是使用壓縮


發佈了33 篇原創文章 · 獲贊 10 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章