目錄
一、Hive誕生的原因
1. 方便對文件及數據的元數據進行管理,提供統一的元數據管理方式。
2. 提供更加簡單的方式來訪問大規模的數據集,使用SQL語言進行數據分析。
二、Hive簡介
1. 數據倉庫基本概念
數據倉庫,英文名稱爲Data Warehouse,可簡寫爲DW或DWH。數據倉庫,是爲企業所有級別的決策制定過程,提供所有類型數據支持的戰略集合。它是單個數據存儲,出於分析性報告和決策支持目的而創建。 爲需要業務智能的企業,提供指導業務流程改進、監視時間、成本、質量以及控制。
下面這個圖是很久以前註釋的了,目前的生產上使用的hive大部分都是1.0以上的版本,後續畫個新的架構和HQL編譯原理圖。
2. 數據處理分類:OLAP與OLTP
數據處理大致可以分成兩大類:聯機事務處理OLTP(on-line transaction processing)、聯機分析處理OLAP(On-Line Analytical Processing)。OLTP是傳統的關係型數據庫的主要應用,主要是基本的、日常的事務處理,例如銀行交易。OLAP是數據倉庫系統的主要應用,支持複雜的分析操作,側重決策支持,並且提供直觀易懂的查詢結果。
3. OLTP
OLTP,也叫聯機事務處理(Online Transaction Processing),表示事務性非常高的系統,一般都是高可用的在線系統,以小的事務以及小的查詢爲主,評估其系統的時候,一般看其每秒執行的Transaction以及Execute SQL的數量。在這樣的系統中,單個數據庫每秒處理的Transaction往往超過幾百個,或者是幾千個,Select 語句的執行量每秒幾千甚至幾萬個。典型的OLTP系統有電子商務系統、銀行、證券等,如美國eBay的業務數據庫,就是很典型的OLTP數據庫。
4. OLAP
OLAP(On-Line Analysis Processing)在線分析處理是一種共享多維信息的快速分析技術;OLAP利用多維數據庫技術使用戶從不同角度觀察數據;OLAP用於支持複雜的分析操作,側重於對管理人員的決策支持,可以滿足分析人員快速、靈活地進行大數據復量的複雜查詢的要求,並且以一種直觀、易懂的形式呈現查詢結果,輔助決策。
5. 特點:
(1)快速性:用戶對OLAP的快速反應能力有很高的要求。系統應能在5秒內對用戶的大部分分析要求做出反 應。
(2)可分析性:OLAP系統應能處理與應用有關的任何邏輯分析和統計分析。
(3)多維性:多維性是OLAP的關鍵屬性。系統必須提供對數據的多維視圖和分析,包括對層次維和多重層次 維的完全支持。
(4)信息性:不論數據量有多大,也不管數據存儲在何處,OLAP系統應能及時獲得信息,並且管理大容量信 息。
三、Hive的服務(角色)
1、用戶訪問接口
CLI(Command Line Interface):用戶可以使用Hive自帶的命令行接口執行Hive QL、設置參數等功能。
JDBC/ODBC:用戶可以使用JDBC或者ODBC的方式在代碼中操作Hive。
Web GUI:瀏覽器接口,用戶可以在瀏覽器中對Hive進行操作(2.2之後淘汰)。
2、Thrift Server:
Thrift服務運行客戶端使用Java、C++、Ruby等多種語言,通過編程的方式遠程訪問Hive。
3、Driver
Hive Driver是Hive的核心,其中包含解釋器、編譯器、優化器等各個組件,完成從SQL語句到MapReduce任務的解析優化執行過程。
4、metastore
Hive的元數據存儲服務,一般將數據存儲在關係型數據庫中,爲了實現Hive元數據的持久化操作,Hive的安裝包中自帶了Derby內存數據庫,但是在實際的生產環境中一般使用mysql來存儲元數據。
四、數據庫與數據倉庫的區別
1、數據庫是對業務系統的支撐,性能要求高,相應的時間短,而數據倉庫則對響應時間沒有太多的要求,當然也是越快越好。
2、數據庫存儲的是某一個產品線或者某個業務線的數據,數據倉庫可以將多個數據源的數據經過統一的規則清洗之後進行集中統一管理。
3、數據庫中存儲的數據可以修改,無法保存各個歷史時刻的數據,數據倉庫可以保存各個時間點的數據,形成時間拉鍊表,可以對各個歷史時刻的數據做分析。
4、數據庫一次操作的數據量小,數據倉庫操作的數據量大。
5、數據庫使用的是實體-關係(E-R)模型,數據倉庫使用的是星型模型或者雪花模型。
6、數據庫是面向事務級別的操作,數據倉庫是面向分析的操作。
Hive與傳統關係型數據庫(RDBMS)對比圖:
五、Hive SQL的基本操作
1、Hive基本操作
展示所有數據庫:
show databases;
切換數據庫:
use database_name;
創建數據庫:
CREATE (DATABASE|SCHEMA) [IF NOT EXISTS] database_name
[COMMENT database_comment]
[LOCATION hdfs_path]
[WITH DBPROPERTIES (property_name=property_value, ...)];
create database database_name;
刪除數據庫:
DROP (DATABASE|SCHEMA) [IF EXISTS] database_name [RESTRICT|CASCADE];
drop database database_name;
注意:當進入hive的命令行開始編寫SQL語句的時候,如果沒有任何相關的數據庫操作,那麼默認情況下,所有的表存在於default數據庫,在hdfs上的展示形式是將此數據庫的表保存在hive的默認路徑下,如果創建了數據庫,那麼會在hive的默認路徑下生成一個database_name.db的文件夾,此數據庫的所有表會保存在database_name.db的目錄下。
2、數據庫表的基本操作
基本語法:
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], ... [constraint_specification])]
[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 [TEMPORARY] [EXTERNAL] TABLE [IF NOT EXISTS] [db_name.]table_name
LIKE existing_table_or_view_name
[LOCATION hdfs_path];
基本數據類型:
| TINYINT
| SMALLINT
| INT
| BIGINT
| BOOLEAN
| FLOAT
| DOUBLE
| DOUBLE PRECISION -- (Note: Available in Hive 2.2.0 and later)
| STRING
| BINARY -- (Note: Available in Hive 0.8.0 and later)
| TIMESTAMP -- (Note: Available in Hive 0.8.0 and later)
| DECIMAL -- (Note: Available in Hive 0.11.0 and later)
| DECIMAL(precision, scale) -- (Note: Available in Hive 0.13.0 and later)
| DATE -- (Note: Available in Hive 0.12.0 and later)
| VARCHAR -- (Note: Available in Hive 0.12.0 and later)
| CHAR -- (Note: Available in Hive 0.13.0 and later)
複雜數據類型:
data_type
| array_type
| map_type
| struct_type
| union_type -- (Note: Available in Hive 0.7.0 and later)
array_type
: ARRAY < data_type >
map_type
: MAP < primitive_type, data_type >
struct_type
: STRUCT < col_name : data_type [COMMENT col_comment], ...>
union_type
: UNIONTYPE < data_type, data_type, ... > -- (Note: Available in Hive 0.7.0 and later)
行格式規範:
row_format
: DELIMITED [FIELDS TERMINATED BY char [ESCAPED BY char]] [COLLECTION ITEMS TERMINATED BY char]
[MAP KEYS TERMINATED BY char] [LINES TERMINATED BY char]
[NULL DEFINED AS char] -- (Note: Available in Hive 0.13 and later)
| SERDE serde_name [WITH SERDEPROPERTIES (property_name=property_value, property_name=property_value, ...)]
文件基本類型:
file_format:
: 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)
| JSONFILE -- (Note: Available in Hive 4.0.0 and later)
| INPUTFORMAT input_format_classname OUTPUTFORMAT output_format_classname
表約束:
constraint_specification:
: [, PRIMARY KEY (col_name, ...) DISABLE NOVALIDATE ]
[, CONSTRAINT constraint_name FOREIGN KEY (col_name, ...) REFERENCES table_name(col_name, ...) DISABLE NOVALIDATE
3.Hive表創建
(1) 創建hive普通表(不包含行定義格式):
CREATE TABLE `test`(
`sku` int,
`currency` string,
`price` decimal(10,2),
`review_total` int,
`review_score` decimal(10,2),
`collection` string)
PARTITIONED BY (
`create_time` string)
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://cdh-001:8020/home/data/user/hive/warehouse/data.db/test'
TBLPROPERTIES (
'transient_lastDdlTime'='1586239332');
//需要創建的表的字段信息,類型於mysql
//與hdfs文件的映射路徑,即hive表展示數據的實際存儲位置,hive本身指存儲元數據,即真實數據的地址
//最後更改表的用戶,更改時間等,這段信息hive會自己創建
(2) 創建自定義行格式的hive表:
create table test2
(
id int,
name string,
hobby array<string>,
address map<string,string>
)
row format delimited
fields terminated by ','
collection items terminated by '-'
map keys terminated by ':';
(3) 創建默認分隔符的hive表:
create table test3
(
id int,
name string,
hobby array<string>,
address map<string,string>
)
row format delimited
fields terminated by '\001'
collection items terminated by '\002'
map keys terminated by '\003';
--或者
create table test3
(
id int,
name string,
hobby array<string>,
address map<string,string>
);
(4) 創建hive的外部表(需要添加external和location關鍵字):
create external table test4
(
id int,
name string,
hobby array<string>,
address map<string,string>
)
row format delimited
fields terminated by ','
collection items terminated by '-'
map keys terminated by ':'
location '/data';
內部表跟外部表的區別:
1、hive內部表創建的時候數據存儲在hive的默認存儲目錄中,外部表在創建的時候需要制定額外的目錄。
2、hive內部表刪除的時候,會將元數據和數據都刪除,而外部表只會刪除元數據,不會刪除數據。應用場景:
內部表:需要先創建表,然後向表中添加數據,適合做中間表的存儲
外部表:可以先創建表,再添加數據,也可以先有數據,再創建表,本質上是將hdfs的某一個目錄的數據跟hive的表關聯映射起來,因此適合原始數據的存儲,不會因爲誤操作將數據給刪除掉。
(5) 創建單分區表
create table test5
(
id int,
name string,
hobby array<string>,
address map<string,string>
)
partitioned by(gender string)
row format delimited
fields terminated by ','
collection items terminated by '-'
map keys terminated by ':';
(6) 創建多分區表
create table test6
(
id int,
name string,
hobby array<string>,
address map<string,string>
)
partitioned by(gender string,age int)
row format delimited
fields terminated by ','
collection items terminated by '-'
map keys terminated by ':';
當創建完分區表之後,在保存數據的時候,會在hdfs目錄中看到分區列會成爲一個目錄,以多級目錄的形式存在。
當創建多分區表之後,插入數據的時候不可以只添加一個分區列,需要將所有的分區列都添加值。
多分區表在添加分區列的值得時候,與順序無關,與分區表的分區列的名稱相關,按照名稱就行匹配。
給分區表添加分區列的值:
alter table table_name add partition(col_name=col_value);
刪除分區列的值:
alter table table_name drop partition(col_name=col_value);
添加分區列的值的時候,如果定義的是多分區表,那麼必須給所有的分區列都賦值。
刪除分區列的值的時候,無論是單分區表還是多分區表,都可以將指定的分區進行刪除。
(7) 分區修復
在使用hive外部表的時候,可以先將數據上傳到hdfs的某一個目錄中,然後再創建外部表建立映射關係,如果在上傳數據的時候,參考分區表的形式也創建了多級目錄,那麼此時創建完表之後,是查詢不到數據的,原因是分區的元數據沒有保存在mysql中,因此需要修復分區,將元數據同步更新到mysql中,此時纔可以查詢到元數據。具體操作如下:
//在hdfs創建目錄並上傳文件
hdfs dfs -mkdir /msb
hdfs dfs -mkdir /msb/age=10
hdfs dfs -mkdir /msb/age=20
hdfs dfs -put /root/data/data /msb/age=10
hdfs dfs -put /root/data/data /msb/age=20
//創建外部表
create external table test
(
id int,
name string,
hobby array<string>,
address map<string,string>
)
partitioned by(age int)
row format delimited
fields terminated by ','
collection items terminated by '-'
map keys terminated by ':'
location '/msb';
//查詢結果(沒有數據)
select * from test;
//修復分區
msck repair table test;
//查詢結果(有數據)
select * from test;
六、插入數據到Hive
1. 導入數據文件到hive表
//加載本地數據到hive表
load data local inpath '/root/data/data' into table test; --(/root/data/data指的是本地linux目錄)
//加載hdfs數據文件到hive表
load data inpath '/data/data' into table test; --(/data/data指的是hdfs的目錄)
注意:
1、load操作不會對數據做任何的轉換修改操作
2、從本地linux load數據文件是複製文件的過程
3、從hdfs load數據文件是移動文件的過程
4、load操作也支持向分區表中load數據,只不過需要添加分區列的值
2. 從查詢語句中獲取數據插入hive表
//注意:這種方式插入數據的時候需要預先創建好結果表
//從表中查詢數據插入結果表
INSERT OVERWRITE TABLE test0 SELECT id,name FROM test1;
//從表中獲取部分列插入到新表中
from test
insert overwrite table test2
select id,name
insert into table test3
select id;
3. 將查詢到的結果插入到文件系統中
//注意:路徑千萬不要填寫根目錄,會把所有的數據文件都覆蓋
//將查詢到的結果導入到hdfs文件系統中
insert overwrite directory '/result' select * from test;
//將查詢的結果導入到本地文件系統中
insert overwrite local directory '/result' select * from test;
4. 使用傳統關係型數據庫的方式插入數據,效率較低
insert into test values(1,'zhangsan');
七、Hive中數據的更新和刪除
在官網中我們可以看到看到hive0.14以上的版本中是支持Update和Delete操作的,但是實際上,是需要事務的支持的,Hive對於事務的支持有很多的限制(官網中有說明)。因此,在使用hive的過程中,我們一般不會進行Update和Delete的操作,而且對數據進行刪除和更新本身也違背了數據倉庫的初衷。
但如果你確實需要有這樣的操作的話,且使用的是CDH平臺,通過Cloudera Manager管理,可以參考我在 hive-site.xml 的 Hive 客戶端高級配置代碼段(安全閥)中添加的配置,而且Hive表的數據在hdfs中存儲的格式必須是ORC格式,因爲目前只有ORCFileformat支持AcidOutputFormat,不僅如此,建表時必須指定參數('transactional' = true),才能支持刪除和更新。
建表語句案例:
CREATE TABLE `test`(
`sku` int,
`currency` string,
`price` decimal(10,2),
`review_total` int,
`review_score` decimal(10,2),
`collection` string)
PARTITIONED BY (
`create_time` string) //分區
CLUSTERED BY (
sku)
INTO 10 BUCKETS //分桶
ROW FORMAT SERDE
'org.apache.hadoop.hive.ql.io.orc.OrcSerde' //必須爲orc格式
STORED AS INPUTFORMAT
'org.apache.hadoop.hive.ql.io.orc.OrcInputFormat' //必須爲orc格式
OUTPUTFORMAT
'org.apache.hadoop.hive.ql.io.orc.OrcOutputFormat'
LOCATION
'hdfs://cdh-001:8020/home/data/user/hive/warehouse/data.db/test'
TBLPROPERTIES (
'last_modified_by'='root',
'last_modified_time'='1568971585',
'transactional'='true', // 這裏必須爲true
'transient_lastDdlTime'='1568971585')
我在Cloudera Manager中 hive-site.xml 的 Hive 客戶端高級配置代碼段 (安全閥)添加的配置:
<property>
<name>hive.support.concurrency</name>
<value>true</value>
<final>true</final>
<description>開啓hive鎖表</description>
</property>
<property>
<name>hive.exec.dynamic.partition.mode</name>
<value>nonstrict</value>
<final>true</final>
<description>開啓動態分區</description>
</property>
<property>
<name>hive.txn.manager</name>
<value>org.apache.hadoop.hive.ql.lockmgr.DbTxnManager</value>
<final>true</final>
<description>支持事務和數據併發</description>
</property>
<property>
<name>hive.compactor.initiator.on</name>
<value>true</value>
<final>true</final>
<description>僅適用於Thrift Metastore服務的一個實例</description>
</property>
<property>
<name>hive.compactor.worker.threads</name>
<value>1</value>
<final>true</final>
<description>Thrift Metastore服務中至少一個實例的正數</description>
</property>
<property>
<name>hive.enforce.bucketing</name>
<value>true</value>
<final>true</final>
</property>
<!--以上的6個配置是必須添加的,下面的是我自己的,可以根據你自身需求確定是否添加-->
<property>
<name>hive.lock.sleep.between.retries</name>
<value>10</value>
<final>true</final>
</property>
<property>
<name>hive.fetch.task.conversion</name>
<value>none</value>
<final>true</final>
</property>
<property>
<name>hive.cli.pretty.output.num.cols</name>
<value>-1</value>
<final>true</final>
<description>格式化描述很多的表語句生成時要使用的列數,如果該值爲-1,則hive將使用自動檢測的最終寬度</description>
</property>
<property>
<name>hive.cli.print.header</name>
<value>true</value>
<final>true</final>
<description>print headers</description>
</property>
<property>
<name>hive.exec.parallel</name>
<value>true</value>
<description>Hive羣集並行計算</description>
</property>
未完待續 . . . . . .