On this page
Use Cases
这是ViewDev的后续操作,用于向视图添加分区意识。
Management 员希望在一组现有的基础表之上创建一组视图作为表/列重命名层,而又不破坏对这些表的任何现有依赖关系。对于只读用户,视图在每种方式上的行为应与基础表完全相同。除其他外,这意味着用户应该能够浏览可用分区。
基本表按日期和小时划分在列(ds,hr)上。除了这种细粒度的分区,用户还希望看到一个虚拟表的粗粒度(仅日期)分区,其中给定日期的分区仅在该天的所有小时级别分区都已完全使用后才出现已加载。
一个视图是在许多基础表和其他视图的复杂连接联合聚合上定义的,所有这些视图本身都已分区。顶层视图也应进行相应的分区,直到为所有基础表加载了相应的分区后,才会出现新的分区。
Approaches
HIVE-1079中提到的一种可能方法是根据基础表的分区自动推断视图分区。然后,诸如 SHOW PARTITIONS 之类的命令可以动态合成虚拟分区 Descriptors。对于用例 1 而言,这相当容易做到,但对于用例 2 和#3 而言则可能非常困难。因此,目前,我们正在研究这种方法。
相反,根据HIVE-1941,我们将要求用户显式声明视图分区作为 CREATE VIEW 的一部分,并通过 ALTER VIEW ADD | DROP PARTITION 显式 Management 分区元数据。这使所有用例都得到满足(同时给用户增加了负担,并占用了更多的元存储空间)。使用这种方法,视图分区和基础表分区之间没有 true 的联系。甚至可以在未分区的表上创建分区视图,或者在视图中包含未被任何视图分区覆盖的数据。这里的一个缺点是,UI 在浏览可用分区时将无法显示上次访问时间和物理信息,例如文件大小。 (理论上,统计数据可以通过显式的 ANALYZE 进行工作,但分析视图需要进行一些工作.)
Syntax
CREATE VIEW [IF NOT EXISTS] view_name [(column_name [COMMENT column_comment], ...) ]
[COMMENT table_comment]
[PARTITIONED ON (col1, col2, ...)]
[TBLPROPERTIES ...]
AS SELECT ...
ALTER VIEW view_name ADD [IF NOT EXISTS] partition_spec partition_spec ...
ALTER VIEW view_name DROP [IF EXISTS] partition_spec, partition_spec, ...
partition_spec:
: PARTITION (partition_col = partition_col_value, partition_col = partiton_col_value, ...)
Notes:
CREATE TABLE 使用 PARTITIONED BY,而 CREATE VIEW 使用 PARTITIONED ON。这种差异是有意的,因为在 CREATE TABLE 中,PARTITIONED BY 子句指定附加的列定义,这些定义将附加到非分区列中。使用 CREATE VIEW,PARTITIONED ON 子句引用(按名称)视图定义已生成的列。只有列名称出现在 PARTITIONED ON 中;但是,为了匹配尾随分区列的 CREATE TABLE 约定,由 PARTITIONED ON 子句引用的列必须是视图定义中的最后一列,并且它们在 PARTITIONED ON 子句中的 Sequences 必须与它们在视图中的 Sequences 匹配定义。
ALTER VIEW ADD/DROP 分区语法与 ALTER TABLE 相同,除了指定 LOCATION 子句是非法的。
不支持在分区(例如 TOUCH/ARCHIVE)上运行的其他 ALTER TABLE 命令。 (但是也许我们需要支持 TOUCH?)
Metastore
在元存储中存储视图分区 Descriptors 时,Hive 会完全忽略该存储 Descriptors。这是因为没有与视图分区相关联的数据,因此无需跟踪用于表模式演化的分区级列 Descriptors,也无需跟踪分区位置。
Strict Mode
Hive 严格模式(通过 hive.mapred.mode = strict 启用)可防止执行缺少分区谓词的查询。这仅适用于基本表分区。这是什么意思?
假设您已将表 T1 分区在 C1 上,并查看 V1,该表选择 FROM T1 WHERE C1 = 5.然后,即使在严格模式下,诸如 SELECT * FROM V1 之类的查询也将成功,因为视图内部的谓词会约束 C1.
同样,假设您有一个视图 V2,它从 T1 中选择(没有 WHERE 子句),并在 C2 上进行了分区。然后,诸如 SELECT * FROM V2 WHERE C2 = 3 之类的查询将失败;即使视图分区列受到约束,底层 T1 的分区列 C1 上也没有谓词。
查看定义更改
当前,更改视图定义需要删除视图并重新创建它。这也意味着删除并重新创建所有现有分区,这可能会非常昂贵。
这意味着对创建或替换视图的后续支持非常重要,它需要保留现有分区(在确认它们仍与新视图定义兼容之后)。
Hook Information
尽管当前在视图分区和基础表分区之间没有连接,但是 Hive 确实将依赖项信息作为 ALTER VIEW ADD PARTITION 的钩子调用的一部分提供。它通过编译表单的内部查询来做到这一点
SELECT * FROM view_name
WHERE view_partition_col1 = 'val1' AND view_partition_col=2 = 'val2' ...
然后捕获该查询的表/分区 Importing,并将其传递给 ALTER VIEW ADD PARTITION 钩子结果。
这允许应用程序自己跟踪依赖关系。将来,Hive 将自动将这些依赖项作为HIVE-1073的一部分填充到元存储中。