轉載:https://juejin.cn/post/6910938451055476750
一、視圖
1.1 簡介
Hive 中的視圖和 RDBMS 中視圖的概念一致,都是一組數據的邏輯表示,本質上就是由一條 SELECT 語句查詢的結果集組成的虛擬表,在數據庫中,存放的只是視圖的定義,而不存放視圖包含的數據項,這些項目仍然存放在原來的基本表結構中。
視圖的作用有:
- 可以簡化數據查詢語句(例如我們可以將一個復雜SQL中的一部分數據創建為一個視圖)
- 通過引入視圖可以提高數據的安全性( 可以被定義為多個表的連接,也可以被定義為只有部分列可見,也可為部分行可見,這里我就可以讓敏感數據不可見)
視圖是純粹的邏輯對象,沒有關聯的存儲 (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; 復制代碼
select * from user_info_view; 復制代碼
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'); 復制代碼
1.7 物化視圖
普通視圖它其實是一張虛表,在視圖中不緩沖記錄,也沒有提高性能,而物化視圖能夠緩存數據,hive把物化視圖當成一張"表",將數據緩存到orc文件中(可以配置),這里我們做個測試,前面在講Hive streaming的時候創建的測試數據,如果有需要可以去看這一節
首先我查詢一張普通的表select weekday,count(1) from ods.u_data_new group by weekday;
可以看到耗時16.524 seconds
接下來我把它做成視圖再查詢一下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
的,所以時間長了可以理解
接下來我們看一下物化視圖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
然后再去修改表使其支持事務,發現都成功了
接下來我們再去嘗試創建物化視圖,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;
一番折騰終於成功的創建了物化視圖,我們發現整個創建過程非常慢,耗時 17.836 seconds,這是因為物化視圖創建的時候,query的執行數據自動落地,"自動"也即在query的執行期間,任何用戶對該物化視圖是不可見的。
創建成功之后,我們去Hdfs 上看,我們發現物化視圖是會真正創建表的
接下來我們嘗試從物化視圖查詢一下數據select * from week_pv_materialized;
發現非常快,這就是物化視圖中,物化一詞的體現。
二. Hive視圖應用場景
- 當Hive中的查詢變得很長或復雜時,通過視圖將這個查詢語句分割成多個小的、更可控的片段可以降低這種復雜度;
- 當Hive中需要通過視圖限制基於條件過濾的數據時;
三. 總結
- 物化視圖是需要事務支持的
- 物化視圖需要事務表上創建