第7章:HiveQL:视图

视图可以允许保存一个查询并像对待表一样对这个查询进行操作。这是一个逻辑结构,因为它不像一个表会存储数据。换句话说,Hive目前暂不支持物化视图。

当一个查询引用一个视图时,这个视图所定义的查询语句将和用户的查询语句组合在一起,供Hive制定查询计划。从逻辑上讲,可以想象为Hive先执行这个视图,然后使用这个结果进行余下后续的查询。

使用视图来降低查询复杂度

一个嵌套子查询的查询:

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

将子查询变成一个视图:

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

简化查询:

1
SELECT lastname FROM shorter_join WHERE id=3;

使用视图来限制基于条件过滤的数据

对于视图来说一个常见的使用场景就是基于一个或多个列的值来限制输出结果。有些数据库允许将视图作为一个安全机制,也就是不给用户直接访问具有敏感数据的原始表,而是提供给用户一个通过WHERE子句限制了的视图,以供访问。Hive目前并不支持这个功能,因为用户必须具有能够访问整个底层原始表的权限,这时视图才能工作。

然而,通过创建视图来限制数据访问可以用来保护信息不被随意查询:

1
2
3
4
hive> CREATE TABLE userinfo (firstname string, lastname string, ssn string, password string);

hive> CREATE VIEW safer_user_info AS
> SELECT firstname,lastname FROM userinfo;

通过WHERE子句限制数据访问的视图,只暴露来自特定部门的员工信息:

1
2
3
4
hive> CREATE TABLE employee (firstname string, lastname string, ssn string, password stirng, department string);

hive> CREATE VIEW techops_employee AS
> SELECT firstname, lastname, ssn FROM userinfo WHERE department='techops';

动态分区中的视图和map类型

Hive可将一行文本作为一个map而非一组固定的列的能力,加上视图功能,就允许用户可以基于同一个物理表构建多个逻辑表。

示例文件:

time^B126546546^Atype^Brequest^Astate^Bny^Acity^Bwhite plains^Apart^Bmuffler

time^B654132456^Atype^Bresponse^Astate^Bny^Acity^Btarrytown^Apart^Bmuffler

创建表:

1
2
3
4
5
6
CREATE EXTERNAL TABLE dynamictable(cols map<string,string>)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\004'
COLLECTION ITEMS TERMINATED BY '\001'
MAP KEYS TERMINATED BY '\002'
STORED AS TEXTFILE;

创建视图,仅取出type值等于request的city、state和part 3个字段:

1
2
3
4
CREATE VIEW orders(state, city, part) AS
SELECT cols["state"], cols["city"], cols["parts"]
FROM dynamictable
WHERE cols["type"] = "request";

视图零零碎碎相关的事情

  • 如果试图语句含有一个LIMIT 100子句,而同时使用到这个视图的查询含有一个LIMIT 200子句,那么用户最终最多只能获取100条记录结果。

    因为定义一个视图实际上并不会“具体化”操作任何实际数据,所以视图实际上是对其所使用到的表和列的一个查询语句固话过程。 
    因此,如果视图所涉及的表或者列不再存在时,会导致视图查询失败。
  • 创建视图时还可以使用其他一些子句

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
        CREATE VIEW IF NOT EXISTS shipments(time, part)
    COMMENT 'Time and parts for shipments.'
    TBLPROPERTIES ('creator' = 'me')
    AS SELECT ...;
    ```

    如果AS SELECT子句中包含没有命名别名的表达式的话,Hive将会使用_CN作为新的列名,其中N表示从0开始的一个整数。
    如果AS SELECT语句不合法的话,那么创建视图过程将失败。

    - 复制视图:

    ``` SQL
    CREATE TABLE shipments2
    LIKE shipments;
  • 删除视图:

    1
    DROP VIEW IF EXISTS shipments;

    不能使用DROP TABLE语句来删除视图

  • 查看视图:

    SHOW TABLES

  • 显式元数据信息:

    和表一样,DESCRIBE 和 DESCRIBE EXTENDED

  • 视图不能够作为INSERT语句或LOAD命令的目标表

  • 视图是只读的,对于视图只允许改变元数据中TBLPROPERTIES属性信息:

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