视图可以允许保存一个查询并像对待表一样对这个查询进行操作。这是一个逻辑结构,因为它不像一个表会存储数据。换句话说,Hive目前暂不支持物化视图。
当一个查询引用一个视图时,这个视图所定义的查询语句将和用户的查询语句组合在一起,然后供Hive制定查询计划。从逻辑上讲,可以想象为Hive先执行这个视图,然后使用这个结果进行余下后续的查询。
当查询变得长或复杂的时候,通过使用视图将这个查询语句分割成多个小的、更可控的片段可以降低这种复杂度。这点和在编程语言中使用函数或者软件设计中的分层设计的概念是一致的。封装复杂的部分可以是最终用户通过重用重复的部分来构建复杂的查询。例如,如下是一个具有嵌套子查询的查询:
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
对于视图来说一个常见的使用场景就是基于一个或多个列的值来限制输出结果。有些数据库允许将视图作为一个安全机制,也就是不给用户直接访问具有敏感数据的原始表,而是提供给用户一个通过WHERE子句限制了的视图,以供访问。Hive目前并不支持这个功能,因为用户必须具有能够访问整个底层原始表的权限,这时视图才能工作。然而,通过创建视图来限制数据访问可以用来保护信息不被随意查询:
如下是通过WHERE子句限制数据访问的视图的另一个例子。在这种情况下,我们希望提供一个员工表视图,只暴露来自特定部门的员工信息:
我们介绍过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:
我们说过,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');