1. 程式人生 > >【Hive】07-HiveQL:檢視

【Hive】07-HiveQL:檢視

檢視可以允許儲存一個查詢並像對待表一樣對這個查詢進行操作。這是一個邏輯結構,因為它不像一個表會儲存資料。換句話說,Hive目前暫不支援物化檢視。 當一個查詢引用一個檢視時,這個檢視所定義的查詢語句將和使用者的查詢語句組合在一起,然後供Hive制定查詢計劃。從邏輯上講,可以想象為Hive先執行這個檢視,然後使用這個結果進行餘下後續的查詢。

1、使用檢視來降低查詢複雜度

當查詢變得長或複雜的時候,通過使用檢視將這個查詢語句分割成多個小的、更可控的片段可以降低這種複雜度。這點和在程式語言中使用函式或者軟體設計中的分層設計的概念是一致的。封裝複雜的部分可以是終端使用者通過重用重複的部分來構建複雜的查詢。例如,如下是一個具有巢狀子查詢的查詢:

FROM (
SELECT * FROM people JOIN cart
ON(cart.people_id=people.id)WHERE firstname='john'
) a SELECT a.lastname WHERE a.id=3;

Hive查詢語句中含有多層巢狀是非常常見的。在下面這個例子中,巢狀子查詢變成了一個檢視:

CREATE VIEW shorter_join AS
SELECT FROM people JOIN cart
ON(cart.people_id=people.id) WHERE firstname='john'

現在就可以像操作表一樣來操作這個檢視了。本次的查詢語句中我們為SELECT語句增加了一個WHERE子句,這樣就大大簡化了之前的那個查詢語句:

SELECT lastname FROM shorter_join WHERE id=3

2、使用檢視來限制基於條件過濾的資料

對於檢視來說一個常見的使用場景就是基於一個或多個列的值來限制輸出結果。有些資料庫允許將檢視作為一個安全機制,也就是不給使用者直接訪問具有敏感資料的原始表,而是提供給使用者一個通過WHERE子句限制了的檢視,以供訪問。Hive目前並不支援這個功能,因為使用者必須具有能夠訪問整個底層原始表的許可權,這時檢視才能工作。然而,通過建立檢視來限制資料訪問可以用來保護資訊不被隨意查詢: 如下是通過WHERE子句限制資料訪問的檢視的另一個例子。在這種情況下,我們希望提供一個員工表檢視,只暴露來自特定部門的員工資訊:

3、動態分割槽中的檢視和map型別

我們介紹過Hive支援array、map和struct資料型別。這些資料型別在傳統資料庫中並不常見,因為它們破壞了第一正規化。Hive可將一行文字作為一個map而非一組固定的列的能力,加上檢視功能,就允許使用者可以基於同一個物理表構建多個邏輯表。

思考下面這個示例檔案。其將整行作為一個map處理,而不是一列固定的列。這裡沒有使用Hive的預設分隔符,這個檔案使用AA(Control+A)作為集合內元素間的分隔符(例如,本例中map的多個鍵.值對之間的分隔符),然後使用^B(Control+B)作為map中的鍵和值之間的分隔符。因為這條記錄較長,所以為了更清晰地表達,我們人為地增加了空行:

下面我們來建立表: 上面的例子中,因為每行只有一個欄位,因此FIELDSTERMINATEDBY語句所指定的分隔符實際上沒有任何影響。 現在我們可以建立這樣一個檢視,其僅取出呼值等於request的city、state和part 3個欄位,並將檢視命名為orderso檢視orders具有3個欄位:state、city和part。 我們建立的第2個檢視名為shipmentse這個檢視返回time和part2個欄位作為列,限制條件是的值為response:

4、檢視零零碎碎相關的事情

我們說過,Hive會先解析檢視,然後使用解析結果再來解析整個查詢語句。然而,作為Hive查詢優化器的一部分,查詢語句和檢視語句可能會合併成一個單一的實際查詢語句。 然而,這個概念檢視仍然適用於檢視和使用這個檢視的查詢語句都包含了一個ORDER BY子句或一個LIMIT子句的情況。這時會在使用這個檢視的查詢語句之前對該檢視進行解析。 例如,如果檢視語句含有一個LIMIT100子句,而同時使用到這個檢視的查詢含有一個LIMIT 200子句,那麼使用者最終最多隻能獲取1傭條結果記錄。 因為定義一個檢視實際上並不會“具體化”操作任何實際資料,所以檢視實際上是對其所使用到的表和列的一個查詢語句固化過程。因此,如果檢視所涉及的表或者列不再存在時,會導致檢視查詢失敗。建立檢視時使用者還可以使用其他一些子句。如下例子修改了我們前面那個例子:

對於表來說, IF NOT ExISTS 和 COMMENT … 子句是可選的,而且和表建立語句具有相同的含義。一個檢視的名稱要和這個檢視所在的資料庫下的其他所有表和檢視的名稱不同。使用者還可以為所有的新列或部分新列增加一個 COMMNET 子句,進行寫註釋.這些註釋並非“繼承”原始表中的定義。同樣地,如果 AS SELECT 子句中包含沒有命名別名的表示式的話,例如 si 州 colsX 計算 cols 中元素的個數),那麼 Hive 將會使用一 N 作為新的列名,其中 N 表示從 0 開始的一個整數。如果 AS SELECT 語句不合法的話,那麼建立檢視過程將失敗。在 AS SELECT 子句之前,使用者可以通過定義 TBLPROPERTIES 來定義表屬性資訊,這點和表相同。上例中,我們定義的屬性為"creator" ,表示這個檢視的建立者名稱。複製檢視,只需要在 LIKE 表示式裡面寫檢視名就可以了:

使用者也可以像以前一樣選擇性使用 EXTERNAL 關鍵字和 LOCATION … 子句。

刪除檢視的方式和刪除表的方式類似:

DROP VIEW IF EXISTS shipments 

;和往常一樣,上面例子中的 IF ExiSTS 語句是可選的。通過 SHOW TABLES 語句(沒有 SHOW VIEWS 這樣的語句)同樣可以檢視到檢視,但是不能使用 DROP TABLE 語句來刪除檢視。和表一樣, DESCRIBE 和DESCRIBE EXTENDED 語句可以顯示檢視的元資料資訊。如果使用後面那個命令.輸出資訊中的“ Detailed Table Information ”部分會有一個 tableType欄位,欄位值顯示的是“ VIRTUAL_VIEW ’。檢視不能夠作為 INSERT 語句或 LOAD 命令的目標表。最後要說明的是,檢視是隻讀的。對於檢視只允許改變元資料中 TBLPROPERTIES 屬性資訊:

ALTER VIEW shipments SET TBLPROPERTIES  ("created_at"="some_timestamp');