文章目錄
一:Hive的基本架構原理:
1.用戶接口:Client
CLI(hive shell)、JDBC/ODBC(java訪問hive)、WEBUI(瀏覽器訪問hive)
2.元數據:Metastore
元數據包括:表名、表所屬的數據庫(默認是default)、表的擁有者、列/分區字段、表的類型(是否是外部表)、表的數據所在目錄等;
默認存儲在自帶的derby數據庫中,推薦使用MySQL存儲Metastore
3.Hadoop
使用HDFS進行存儲,使用MapReduce進行計算。
4.驅動器:Driver
(1)解析器(SQL Parser):將SQL字符串轉換成抽象語法樹AST,這一步一般都用第三方工具庫完成,比如antlr;對AST進行語法分析,比如表是否存在、字段是否存在、SQL語義是否有誤。
(2)編譯器(Physical Plan):將AST編譯生成邏輯執行計劃。
(3)優化器(Query Optimizer):對邏輯執行計劃進行優化。
(4)執行器(Execution):把邏輯執行計劃轉換成可以運行的物理計劃。對於Hive來說,就是MR/Spark。
Hive通過給用戶提供的一系列交互接口,接收到用戶的指令(SQL),使用自己的Driver,結合元數據(MetaStore),將這些指令翻譯成MapReduce,提交到Hadoop中執行,最後,將執行返回的結果輸出到用戶交互接口。
二:Hive的作用和優勢:
-
基於Hadoop的數據倉庫解決方案
- Hive是基於Hadoop的一個數據倉庫工具,將結構化的數據文件映射爲數據庫表。
- 提供類sql的查詢語言HQL(Hive Query Language)
- 數據不放在hive上,放在HDFS上
- 由Facebook開源用於解決海量結構化日誌的數據統計。
- 執行程序運行在Yarn上
-
優勢:
- 提供了簡單的優化模型
- HQL類sql語法,簡化MR開發
- 支持在HDFS和HBase上臨時查詢數據
- 支持用戶自定義函數,格式
- 成熟JDBC和ODBC驅動程序,用於ETL和BI
- 穩定可靠的批處理
- 支持在不同計算框架運行
-
缺點:
-
Hive的執行延遲比較高,因此Hive常用於數據分析,對實時性要求不高的場合
-
迭代式算法無法表達
-
數據挖掘方面不擅長
-
Hive自動生成的MapReduce作業,通常情況下不夠智能化
-
Hive調優比較困難,粒度較粗
-
三:Hive的數據類型:
類型 | 示例 | 類型 | 示例 |
---|---|---|---|
TINYINT | 10Y | SMALLINT | 10S |
INT | 10 | BIGINT | 100L |
FLOAT | 1.342 | BINARY | 1010 |
DECIMAL | 3.14 | STRING | ’Book’ or "Book" |
BOOLEAN | TRUE | VARCHAR | ’Book’ or "Book" |
CHAR | ’YES’or"YES" | TIMESTAMP | ’2013-01-31 00:13:00:345’ |
DATE | ’2013-01-31’ | DOUBLE | 1.234 |
ARRAY | [‘Apple’,‘Orange’] | ARRAY | a[0] = 'Apple’ |
MAP | {‘A’:‘Apple’,‘0’:‘Orange’} | MAP<STRING, STIRNG> | b[‘A’] = 'Apple’ |
STRUCT | {‘Apple’,2} | STRUCTfruit: | c.weight = 2 |
四:Hive元數據結構:
元數據管理:
**元數據包括:**表名、表所屬的數據庫(默認是default)、表的擁有者、列/分區字段、表的類型(是否是外部表)、表的數據所在目錄等
- 記錄數據倉庫中的模型定義
- 默認存儲在自帶的derby數據庫中,推薦使用MySQL存儲Metastore
數據結構 | 描述 | 邏輯關係 | 物理存儲 |
---|---|---|---|
Database | 數據庫 | 表的集合 | 文件夾 |
Table | 表 | 行數據的集合 | 文件夾 |
Partition | 分區 | 用於分割數據 | 文件夾 |
Buckets | 分桶 | 用於分佈數據 | 文件 |
Row | 行 | 行記錄 | 文件中的行 |
Columns | 列 | 列記錄 | 每行指定的位置 |
Views | 視圖 | 邏輯概念,可跨越多張表 | 不存儲數據 |
Index | 索引 | 記錄統計數據信息 | 文件夾 |
五:Hive的數據庫表分類:
內部表:
HDFS中爲所屬數據庫目錄下的子文件夾
數據完全由Hive管理,刪除表(元數據)會刪除數據,雖然存儲路徑在HDFS上,但由Hive自己管理。
外部表:
數據保存在指定位置的HDFS路徑中
Hive不完全管理數據,刪除表(元數據)不會刪除數據
注意:
PS:
內部表數據存儲的位置是hive.metastore.warehouse.dir(默認:/user/hive/warehouse),
外部表數據的存儲位置由自己制定(如果沒有LOCATION,Hive將在HDFS上的/user/hive/warehouse文件夾下以外部表的表名創建一個文件夾,並將屬於這個表的數據存放在這裏)
六:Hive基本命令:
命令語句hql結構幾乎和mysql一致
-
創建數據庫:
create database mydemo;
-
創建內部表:
create table userinfos( userid int, username string );
-
創建外部表:
create external table customs( cust_id string, cust_name string, age int ) row format delimited fields terminated by ',' location '/data';
-
插入表數據:
insert into userinfos values('1','zs');
-
查詢表數據:
select count(*) from userinfos;
-
修改表元數據:
ALTER TABLE employee RENAME TO new_employee; ALTER TABLE c_employee SET TBLPROPERTIES ('comment'='New name, comments'); ALTER TABLE employee_internal SET SERDEPROPERTIES ('field.delim' = '$’); ALTER TABLE c_employee SET FILEFORMAT RCFILE; -- 修正表文件格式 -- 修改表的列操作 ALTER TABLE employee_internal CHANGE old_name new_name STRING; -- 修改列名 ALTER TABLE c_employee ADD COLUMNS (work string); -- 添加列 ALTER TABLE c_employee REPLACE COLUMNS (name string); -- 替換列改數據類型
-
使用shell命令:
!hdfs dfs -text /opt/soft/hive110/mydemo.db/userinfos/000000_0
Hive的更新和刪除操作需要配置事務
七:Hive建表高階語句:CTAS-WITH
CATS-as select 方式建表
create table ctas_employee as select * from employee
CTE(CATS with common table expression )
CREATE TABLE cte_employee AS
WITH
r1 AS (SELECT name FROM r2 WHERE name = 'Michael'),
r2 AS (SELECT name FROM employee WHERE sex_age.sex= 'Male'),
r3 AS (SELECT name FROM employee WHERE sex_age.sex= 'Female')
SELECT * FROM r1 UNION ALL SELECT * FROM r3;
hive和mysql對比
# mysql
select r.username,r.classname,r.score,r.score/l.countScore *100
from(select classname,sum(score) countScore from scores group by classname) l
inner join(select u.*,s.classname,s.score from userinfos u inner join scores s on u.userid=s.userid) r
on l.classname = r.classname
# hive
with a1 as(select classname,sum(score) countScore from scores group by classname),a2 as(select u.*,s.classname,s.score from userinfos u inner join scores s on u.userid=s.userid) select a2.username,a2.classname,a2.score,(a2.score/a1.countScore*100) from a1 inner join a2 on a1.classname=a2.classname;
創建臨時表
臨時表是應用程序自動管理在複雜查詢期間生成的中間數據的方法
-
表只對當前session有效,session退出後自動刪除
-
表空間位於/tmp/hive-<user_name>(安全考慮)
-
如果創建的臨時表表名已存在,實際用的是臨時表
CREATE TEMPORARY TABLE tmp_table_name1 (c1 string);
CREATE TEMPORARY TABLE tmp_table_name2 AS..
CREATE TEMPORARY TABLE tmp_table_name3 LIKE..
八:Hive數據分區:-partition
-
分區主要用於提高性能
- 分區列的值將表劃分爲segments(文件夾)
- 查詢時使用分區列和常規列類似
- 查詢Hive自動過濾不用於提高性能的分區
-
分爲靜態分區和動態分區
靜態分區
–相當於指定手動創建ALTER TABLE employee_partitioned ADD PARTITION (year=2019,month=3) PARTITION (year=2019,month=4); ALTER TABLE employee_partitioned DROP PARTITION (year=2019,
insert into 追加 insert overwrite into覆蓋 拉鍊表 全量表
- 添加靜態分區的數據
# 塞值 insert into table mypart partition(gender='male') values(1,'zs'); # 塞表 靜態塞值的時候不需要塞分區字段名 insert overwrite table mypart partition(gender='female') select userid,username from userinfos; # 如果塞的表和分區的分區字段不一致,會強行把表的分區字段變爲一致 # 就是到這個分區,這個分區的字段都變爲一致。
動態分區
- 使用動態分區需設定屬性–開啓動態分區
set hive.exec.dynamic.partition=true; set hive.exec.dynamic.partition.mode=nonstrict;
- 動態分區設置方法
insert into table employee_partitioned partition(year, month)# 設置主分區和子分區 select name,array('Toronto') as work_place, named_struct("sex","male","age",30) as sex_age, map("python",90) as skills_score, map("r&d", array('developer')) as depart_title, year(start_date) as year,month(start_date) as month from employee_hr eh;
- 設置動態分區的個數上限
set hive.exec.max.created.files=600000;
- 加載本地數據文件到hive數據庫表
load data local inpath '/opt/wyw.xlsx' overwrite into table mydemo.customs2;
- 將一張表導入另一張表
# 給一張表的對應分區裏插入另一張表的數據,動態塞值的時候需要塞分區字段名 insert into table mypart partition(gender) select userid,username,gender from userinfos;
insert overwrite table userinfos partition(year,month) select userid,username,age,regexp_replace(birthday,'/','-'),gender,split(birthday,'/')[0] as year, split(birthday,'/')[1] as month from customs3;
九:Hive數據分桶:-Buckets
分桶對應於HDFS中的文件
- 更高的查詢處理效率
- 使抽樣(sampling)更高效
- 根據“桶列”的哈希函數將數據進行分桶
分桶只有動態分桶
-
set hive.enforce.bucketing=true;
定義分桶
-
# 分桶列是表中已有列 # 分桶數是2的n次方 # 直接分文件,不是分文件夾 create table xxx() clustered by (employee_id) into 2 buckets
分桶抽樣(Sampling):
-
隨機抽樣基於整行數據
SELECT * FROM table_name TABLESAMPLE(BUCKET 3 OUT OF 32 ON rand()) s;
-
隨機抽樣基於指定列
# SELECT * FROM table_name TABLESAMPLE(BUCKET 3 OUT OF 32 ON id) s;
-
隨機抽樣基於block size
SELECT * FROM table_name TABLESAMPLE(10 PERCENT) s; SELECT * FROM table_name TABLESAMPLE(1M) s; SELECT * FROM table_name TABLESAMPLE(10 rows) s;
create table customs3(userid int, username string,age int,birthday string,gender string) row format delimited fields terminated by ','
索引–分區–分桶:
索引和分區最大的區別
就是索引不分割數據庫,分區分割數據庫。
索引其實就是拿額外的存儲空間換查詢時間,但分區已經將整個大數據庫按照分區列拆分成多個小數據庫了。
分區和分桶最大的區別
就是分桶隨機分割數據庫,分區是非隨機分割數據庫。
因爲分桶是按照列的哈希函數進行分割的,相對比較平均;而分區是按照列的值來進行分割的,容易造成數據傾斜。
其次兩者的另一個區別就是分桶是對應不同的文件(細粒度),分區是對應不同的文件夾(粗粒度)。
注意:普通表(外部表、內部表)、分區表這三個都是對應HDFS上的目錄,桶表對應是目錄裏的文件
十:Hive視圖操作:
視圖概述
-
通過隱藏子查詢、連接和函數來簡化查詢的邏輯結構
-
虛擬表,從真實表中選取數據
-
只保存定義,不存儲數據
-
如果刪除或更改基礎表,則查詢視圖將失敗
-
視圖是隻讀的,不能插入或裝載數據
應用場景
-
將特定的列提供給用戶,保護數據隱私
-
查詢語句複雜的場景
視圖操作命令:
CREATE VIEW view_name AS SELECT statement; -- 創建視圖
-- 創建視圖支持 CTE, ORDER BY, LIMIT, JOIN, etc.
SHOW TABLES; -- 查找視圖 (SHOW VIEWS 在 hive v2.2.0之後)
SHOW CREATE TABLE view_name; -- 查看視圖定義
DROP view_name; -- 刪除視圖
ALTER VIEW view_name SET TBLPROPERTIES ('comment' = 'This is a view');
--更改視圖屬性
ALTER VIEW view_name AS SELECT statement; -- 更改視圖定義
Hive側視圖(lateral view)
-
常與表生成函數結合使用,將函數的輸入和輸出連接
-
OUTER關鍵字:即使output爲空也會生成結果
# split將對應字段值通過,分割然後explode把 select name,work_place,loc from employee lateral view outer explode(split(null,',')) a as loc;
-
進行wordcount分割
# 建表 create table wordcount2(word string) # 導數據 world,see,me load data local inpath '/opt/niceday.txt' overwrite into table mydemo Loading data to table mydemo.wordcount2 # 聚合側視圖查詢 select count(*),loc from wordcount2 lateral view outer explode(split(word,',')) a as loc group by loc;
-
支持多層級
select name,wps,skill,score from employee lateral view explode(work_place) work_place_single as wps lateral view explode(skills_score) sks as skill,score;
-
通常用於規範化行或解析JSON
十一:Hive 導表方式:
內部表:
-
創建
create table userinfos( userid int, username string );
-
直接插入數據到表
insert into table mypart values(1,'zs');
-
從表中導入數據到表
# 給一張表的對應分區裏插入另一張表的數據,動態塞值的時候需要塞分區字段名 insert into table mypart select userid,username,gender from userinfos;
-
從本地文件導入數據到表
load data local inpath '/opt/wyw.xlsx' overwrite into table mydemo.customs2;
外部表:
-
創建並導入本地文件,還設置了分割方式
create external table customs( cust_id string, cust_name string, age int ) row format delimited fields terminated by ',' location '/data';
-
直接插入數據到表
insert into table mypart values(1,'zs');
-
從表中導入數據到表
insert into table mypart select userid,username,gender from userinfos;