Hive系列(二)Hive的基本原理與操作--全的不行!!!

一: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;
    
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章