hive 視圖view和物化視圖materialized view


轉載:https://juejin.cn/post/6910938451055476750

一、視圖

1.1 簡介

Hive 中的視圖和 RDBMS 中視圖的概念一致,都是一組數據的邏輯表示,本質上就是由一條 SELECT 語句查詢的結果集組成的虛擬表,在數據庫中,存放的只是視圖的定義,而不存放視圖包含的數據項,這些項目仍然存放在原來的基本表結構中。

視圖的作用有:

  1. 可以簡化數據查詢語句(例如我們可以將一個復雜SQL中的一部分數據創建為一個視圖)
  2. 通過引入視圖可以提高數據的安全性( 可以被定義為多個表的連接,也可以被定義為只有部分列可見,也可為部分行可見,這里我就可以讓敏感數據不可見)

視圖是純粹的邏輯對象,沒有關聯的存儲 (Hive 3.0.0 引入的物化視圖除外),當查詢引用視圖時,Hive 可以將視圖的定義與查詢結合起來,例如將查詢中的過濾器推送到視圖中。

1.2 創建視圖

CREATE VIEW [IF NOT EXISTS] [db_name.]view_name -- 視圖名稱 [(column_name [COMMENT column_comment], ...) ] --列名 [COMMENT view_comment] --視圖注釋 [TBLPROPERTIES (property_name = property_value, ...)] --額外信息 AS SELECT ...; 復制代碼 復制代碼

在 Hive 中可以使用 CREATE VIEW 創建視圖,如果已存在具有相同名稱的表或視圖,則會拋出異常,建議使用 IF NOT EXISTS 預做判斷。在使用視圖時候需要注意以下事項:

  • 視圖是只讀的,不能用作 LOAD / INSERT / ALTER 的目標;

  • 在創建視圖時候視圖就已經固定,對基表的后續更改(如添加列)將不會反映在視圖;

  • 刪除基表並不會刪除視圖,需要手動刪除視圖;

  • 視圖可能包含 ORDER BY 和 LIMIT 子句。如果引用視圖的查詢語句也包含這類子句,其執行優先級低於視圖對應字句。例如,視圖 custom_view 指定 LIMIT 5,查詢語句為 select * from custom_view LIMIT 10,此時結果最多返回 5 行。

  • 創建視圖時,如果未提供列名,則將從 SELECT 語句中自動派生列名;

  • 創建視圖時,如果 SELECT 語句中包含其他表達式,例如 x + y,則列名稱將以_C0,_C1 等形式生成,有一點需要注意的是,C0 並不是從第一個表達式字段開始的,而是從第一個定義字段開始的

    CREATE VIEW IF NOT EXISTS user_info_view AS SELECT user_id,cid,ckid,username,"man" ,1+2 from user_info; 復制代碼

    image-20201227204009933

select * from user_info_view; 復制代碼

image-20201227204256751

1.3 查看視圖

-- 查看所有視圖: 沒有單獨查看視圖列表的語句,只能使用 show tables show tables; -- 查看某個視圖 desc view_name; -- 查看某個視圖詳細信息 desc formatted view_name; 復制代碼

1.4 刪除視圖

DROP VIEW [IF EXISTS] [db_name.]view_name; 復制代碼

刪除視圖時,如果被刪除的視圖被其他視圖所引用,這時候程序不會發出警告,但是引用該視圖其他視圖已經失效,需要進行重建或者刪除。

1.5 修改視圖

ALTER VIEW [db_name.]view_name AS select_statement; 復制代碼

被更改的視圖必須存在,且視圖不能具有分區,如果視圖具有分區,則修改失敗。

1.6 修改視圖屬性

語法:

ALTER VIEW [db_name.]view_name SET TBLPROPERTIES table_properties; table_properties: : (property_name = property_value, property_name = property_value, ...) 復制代碼

示例:

ALTER VIEW user_info_view SET TBLPROPERTIES ('userName'='kingcall','date'='2020-12-27'); 復制代碼

image-20201227204651788

1.7 物化視圖

普通視圖它其實是一張虛表,在視圖中不緩沖記錄,也沒有提高性能,而物化視圖能夠緩存數據,hive把物化視圖當成一張"表",將數據緩存到orc文件中(可以配置),這里我們做個測試,前面在講Hive streaming的時候創建的測試數據,如果有需要可以去看這一節

首先我查詢一張普通的表select weekday,count(1) from ods.u_data_new group by weekday; 可以看到耗時16.524 seconds

image-20201227205200002

接下來我把它做成視圖再查詢一下create view week_pv as select weekday,count(1) from ods.u_data_new group by weekday;接下來我查詢剛才的視圖select * from week_pv;可以看到耗時幾乎沒變,甚至更長了15.611 seconds

其實這也可以立即,因為此時的SQL 其實等價於 select * from (select weekday,count(1) from ods.u_data_new group by weekday)tmp 的,所以時間長了可以理解

image-20201227205434059

接下來我們看一下物化視圖create materialized view week_pv_materialized as select weekday,count(1) from ods.u_data_new group by weekday; 然后你就得到了下面的錯誤信息

FAILED: SemanticException org.apache.hadoop.hive.ql.parse.SemanticException: Automatic rewriting for materialized view cannot be enabled if the materialized view uses non-transactional tables (state=42000,code=40000)
復制代碼

這里我們就不詳細解釋怎么去開啟事務了,因為我們單獨有一節就是將這個的,所以我們的重點還是回到物化視圖上來。

既然如此我們就修改表的屬性,使其支持事務 ALTER table ods.u_data_new SET TBLPROPERTIES ('transactional'='true'); 然后又報錯了,說是存儲類型必須是orc

Error: Error while processing statement: FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask. Unable to alter table. The table must be stored using an ACID compliant format (such as ORC): ods.u_data_new (state=08S01,code=1) 復制代碼

好的那我們就修改存儲類型為orc ALTER TABLE ods.u_data_new SET FILEFORMAT orc 然后再去修改表使其支持事務,發現都成功了

image-20201227211829587

接下來我們再去嘗試創建物化視圖,TMD 還是報錯了

Error: Error while compiling statement: FAILED: SemanticException [Error 10265]: This command is not allowed on an ACID table ods.u_data_new with a non-ACID transaction manager. 
Failed command: create materialized view week_pv_materialized as select weekday,count(1) from ods.u_data_new group by weekday (state=42000,code=10265)
復制代碼

說我們沒有事務管理器,看起來我們開需要配置hive 讓其開啟事務管理,但是這個平時用的不是很多,所以我們只在當前會話里設置一下

SET hive.support.concurrency = true;
SET hive.enforce.bucketing = true;
SET hive.exec.dynamic.partition.mode = nonstrict;
SET hive.txn.manager = org.apache.hadoop.hive.ql.lockmgr.DbTxnManager;
SET hive.compactor.initiator.on = true;
SET hive.compactor.worker.threads = 1;
復制代碼

這下應該差不多了吧,那我們再嘗試創建一下我們的物化視圖,發現還是報錯了,這個時候我發現我們直接從select * from ods.u_data_new;這張表查詢都報錯了

Error: java.io.IOException: java.lang.RuntimeException: ORC split generation failed with exception: org.apache.orc.FileFormatException: Malformed ORC file hdfs://kingcall:9000/user/hive/warehouse/ods.db/u_data_new/000000_0. Invalid postscript. (state=,code=0)
復制代碼

我還是老老實實創建一個事務表吧,不修改了,然后我們將數據導入到下面這張表里

CREATE TABLE `ods.u_data_new_transactional`( `userid` int, `movieid` int, `rating` int, `weekday` int ) stored as orc tblproperties('transactional'='true'); 復制代碼

insert overwrite table ods.u_data_new_transactional select * from ods.u_data_new; 事務表創建好之后,我們再嘗試創建一下物化視圖create materialized view week_pv_materialized as select weekday,count(1) from ods.u_data_new_transactional group by weekday;

image-20201227215328547

一番折騰終於成功的創建了物化視圖,我們發現整個創建過程非常慢,耗時 17.836 seconds,這是因為物化視圖創建的時候,query的執行數據自動落地,"自動"也即在query的執行期間,任何用戶對該物化視圖是不可見的。

創建成功之后,我們去Hdfs 上看,我們發現物化視圖是會真正創建表的

image-20201227215517268

接下來我們嘗試從物化視圖查詢一下數據select * from week_pv_materialized;

image-20201227215730444

發現非常快,這就是物化視圖中,物化一詞的體現。

二. Hive視圖應用場景

  • 當Hive中的查詢變得很長或復雜時,通過視圖將這個查詢語句分割成多個小的、更可控的片段可以降低這種復雜度;
  • 當Hive中需要通過視圖限制基於條件過濾的數據時;

三. 總結

  1. 物化視圖是需要事務支持的
  2. 物化視圖需要事務表上創建



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM