适用于:
Databricks SQL
具体化视图是预计算结果可用于查询的视图,并且可以更新以反映输入中的更改。 每次刷新具体化视图时,都会重新计算查询结果,以反映上游数据集中的变化。 所有具体化视图都由 ETL 管道支持。 可以手动或按计划刷新具体化视图。
若要详细了解如何执行手动刷新,请参阅 REFRESH(MATERIALIZED VIEW 或 STREAMING TABLE)。
若要详细了解如何计划刷新,请参阅 示例 或 ALTER MATERIALIZED VIEW。
具体化视图只能使用 Pro 或无服务器 SQL 仓库或在管道中创建。
注意
无服务器 Lakeflow 声明性管道支持对具体化视图和流式处理表进行的创建和刷新操作。 可以使用目录资源管理器在 UI 中查看有关支持管道的详细信息。 请参阅什么是目录资源管理器?。
语法
{ CREATE OR REPLACE MATERIALIZED VIEW | CREATE MATERIALIZED VIEW [ IF NOT EXISTS ] }
view_name
[ column_list ]
[ view_clauses ]
AS query
column_list
( { column_name column_type column_properties } [, ...]
[ , table_constraint ] [...])
column_properties
{ NOT NULL | COMMENT column_comment | column_constraint | MASK clause } [ ... ]
view_clauses
{ PARTITIONED BY (col [, ...]) |
CLUSTER BY clause |
COMMENT view_comment |
DEFAULT COLLATION UTF8_BINARY |
TBLPROPERTIES clause |
SCHEDULE [ REFRESH ] schedule_clause |
schedule |
WITH { ROW FILTER clause } } [...]
schedule
{ SCHEDULE [ REFRESH ] schedule_clause |
TRIGGER ON UPDATE [ AT MOST EVERY trigger_interval ] }
schedule_clause
{ EVERY number { HOUR | HOURS | DAY | DAYS | WEEK | WEEKS } |
CRON cron_string [ AT TIME ZONE timezone_id ] }
参数
REPLACE
如果指定了该参数,则替换已存在的视图及其内容。
如果不存在
如果视图不存在,则创建它。 如果已存在具有此名称的视图,则忽略
CREATE MATERIALIZED VIEW语句。最多可以指定
IF NOT EXISTS或OR REPLACE中的一项。-
新创建的视图的名称。 完全限定的视图名称必须是独一无二的。
column_list
(可选)在视图的查询结果中标记列。 如果提供列列表,则列别名的数量必须与查询中的表达式数量一致。 如果未指定列列表,则别名派生自视图主体。
-
列名必须具有唯一性,并映射到查询的输出列。
列类型
指定列的数据类型。 并非 Azure Databricks 支持的所有数据类型都受具体化视图支持。
column_comment
描述列的可选
STRING文本。 此选项必须与column_type一起指定。 如果未指定列类型,则会跳过列注释。column_constraint
向具体化视图中的列添加信息性主键或信息性外键约束。 如果未指定列类型,则会跳过列约束。
-
重要
此功能目前以公共预览版提供。
添加列掩码函数以对敏感数据进行匿名化处理。 该列的所有后续查询将会收到对该列计算该函数(而不是该列的原始值)的结果。 这对于细粒度的访问控制目的非常有用,在这种情况下,该函数可以检查调用用户的身份或组成员身份,以便决定是否编辑该值。 如果未指定列类型,则会跳过列掩码。
-
table_constraint
向具体化视图中的表添加信息性主键或信息性外键约束。 如果未指定列类型,则会跳过表约束。
view_clauses
为新具体化视图指定分区、注释、用户定义的属性和刷新计划(可选)。 每个子子句只能指定一次。
-
表中用于对表进行分区的列可选列表。
注意
Liquid 聚类分析提供灵活的优化解决方案进行聚类分析。 考虑对具体化视图使用
CLUSTER BY而不是PARTITIONED BY。 -
按列子集聚类的可选子句。 结合使用自动液体聚类分析,
CLUSTER BY AUTODatabricks 智能地选择聚类分析键以优化查询性能。 请参阅对表使用 liquid 聚类分析。液体聚类分析不能与
PARTITIONED BY。 评论 查看评论
用于描述表的
STRING文本。默认排序规则UTF8_BINARY
适用于:
Databricks SQL
Databricks Runtime 17.1 及更高版本强制将具体化视图的默认排序规则设置为
UTF8_BINARY。 如果创建视图的架构使用的默认排序规则不是UTF8_BINARY,则此子句是必需的。 物化视图的默认排序规则被用作视图主体中的默认排序规则。-
可以选择设置一个或多个用户定义的属性。
使用此设置指定用于运行此语句的 Lakeflow 声明性管道运行时通道。 将
pipelines.channel属性的值设置为"PREVIEW"或"CURRENT"。 默认值是"CURRENT"。 有关 Lakeflow 声明性管道通道的详细信息,请参阅 Lakeflow 声明性管道运行时通道。 附表
计划可以是
SCHEDULE语句或TRIGGER语句。REFRESHSCHEDULE [ ] schedule_clause
EVERY number { HOUR | HOURS | DAY | DAYS | WEEK | WEEKS }若要安排定期执行刷新,请使用
EVERY语法。 如果指定了EVERY语法,则流式处理表或具体化视图将基于提供的值按指定间隔定期刷新,例如HOUR、HOURS、DAY、DAYS、WEEK或WEEKS。 下表列出了接受的number整数值。时间单位 整数值 HOUR or HOURS1 < = H < = 72 DAY or DAYS1 < = D < = 31 WEEK or WEEKS1 < = W < = 8 注意
包含的时间单位的单数形式和复数形式在语义上是等效的。
CRON cron_string [ AT TIME ZONE timezone_id ]使用 quartz cron 值计划刷新。 接受有效的 time_zone_values。
AT TIME ZONE LOCAL不受支持。如果
AT TIME ZONE不存在,则使用会话时区。 如果AT TIME ZONE不存在并且未设置会话时区,则会引发错误。SCHEDULE在语义上等效于SCHEDULE REFRESH。
TRIGGER ON UPDATE [ 最多每个trigger_interval ]
重要
此功能
TRIGGER ON UPDATE在 Beta 版中。 若要在工作区中启用此功能,请联系 Databricks 代表。(可选)将表设置为在更新上游数据源时刷新,最多每分钟一次。 设置一个值
AT MOST EVERY,以便在刷新之间至少需要一个最短的时间。上游数据源必须是外部表或托管的 Delta 表(包括具体化视图或流式处理表),或者依赖项仅限于支持的表类型的托管视图。
启用 文件事件 可以使触发器更具性能,并增加触发器更新的一些限制。
trigger_interval这是至少 1 分钟的 INTERVAL 语句。TRIGGER ON UPDATE具有以下限制- 每个具体化视图使用表触发器的上游数据源不超过 10 个。
- 最多使用表触发器的 50 个具体化视图或流式处理表(在上游数据源上启用文件事件会消除此限制)。
- 对于外部 Delta 表中的源数据,每个更改集的行数限制为 10,000 行(在上游数据源上启用文件事件会删除此限制)。
- 子
AT MOST EVERY句默认为 1 分钟,不能小于 1 分钟。
WITH ROW FILTER 子句
重要
此功能目前以公共预览版提供。
向表中添加行筛选器函数。 来自该表的所有后续查询都会收到函数计算结果为布尔值 TRUE 的行的子集。 这对于细粒度的访问控制目的非常有用,在这种情况下,该函数可以检查调用用户的身份或组成员身份,以决定是否筛选特定行。
-
AS 查询
从基表或其他视图中构造视图的查询。
所需的权限
创建具体化视图 (MV) 的用户是 MV 所有者,需要具有以下权限:
- 对 MV 引用的基表的
SELECT特权。 - 对父目录具有
USE CATALOG权限,对父架构具有USE SCHEMA权限。 - 对 MV 架构的
CREATE MATERIALIZED VIEW特权。
为了让用户能够刷新 MV,他们需要:
- 对父目录具有
USE CATALOG权限,对父架构具有USE SCHEMA权限。 - MV 所有权或对 MV 的
REFRESH特权。 - MV 所有者必须对 MV 引用的基表具有
SELECT特权。
为了让用户能够查询 MV,他们需要:
- 对父目录具有
USE CATALOG权限,对父架构具有USE SCHEMA权限。 - 对具体化视图的
SELECT特权。
行筛选器和列掩码
重要
此功能目前以公共预览版提供。
行筛选器允许指定在表扫描提取行时作为筛选器应用的函数。 这些筛选器可确保后续查询仅返回筛选器谓词的计算结果为 true 的行。
每当表扫描提取行时,列掩码就会让你将列值掩码。 将来所有涉及该列的查询都会收到对该列计算函数后的结果,并替换列的原始值。
有关如何使用行筛选器和列掩码的详细信息,请参阅 行筛选器和列掩码。
管理行筛选器和列掩码
应通过 CREATE 语句添加具体化视图上的行筛选器和列掩码。
行为
- 以定义者身份刷新:当
REFRESH MATERIALIZED VIEW语句刷新具体化视图时,行筛选器函数将以定义者的权限(以表所有者的身份)运行。 这意味着,表刷新使用已创建该具体化视图的用户的安全性上下文。 - 查询:虽然大多数筛选器都以定义者的权限运行,但检查用户上下文(例如 和
CURRENT_USER)的函数是例外。 这些函数作为调用程序运行。 此方法基于当前用户的上下文强制实施特定于用户的数据安全和访问控制。 - 在包含行筛选器和列掩码的源表上创建具体化视图时,具体化视图的刷新始终是完全刷新。 完全刷新使用最新定义重新处理源中的所有可用数据。 这可确保使用最新的数据和定义来评估和应用源表上的安全策略。
可观测性
使用 DESCRIBE EXTENDED、INFORMATION_SCHEMA 或目录资源管理器检查适用于给定具体化视图的现有行筛选器和列掩码。 此功能允许用户审核和查看具体化视图上的数据访问和保护措施。
限制
- 当在可以为 NULL 的列上具有
sum聚合的具体化视图从该列中移除了最后一个非 NULL 值 - 因此该列中只剩下NULL个值时,具体化视图的结果聚合值将返回零而不是NULL。 - 列引用不需要别名。 非列引用表达式需要别名,如以下示例所示:
- 允许:
SELECT col1, SUM(col2) AS sum_col2 FROM t GROUP BY col1 - 不允许:
SELECT col1, SUM(col2) FROM t GROUP BY col1
- 允许:
- 必须手动指定
NOT NULL和PRIMARY KEY,才能成为有效的语句。 - 具体化视图不支持标识列或代理项键。
- 具体化视图不支持
OPTIMIZE和VACUUM命令。 维护是自动进行的。 - 具体化视图不支持定义数据质量约束的预期。
示例
-- Create a materialized view if it doesn't exist
> CREATE MATERIALIZED VIEW IF NOT EXISTS subscribed_movies
AS SELECT mo.member_id, mb.full_name, mo.movie_title
FROM movies AS mo INNER JOIN members AS mb ON mo.member_id = mb.id;
-- Create and schedule a materialized view to be refreshed every day.
-- Note: All columns in a GROUP BY need to be explicitly aliased
> CREATE MATERIALIZED VIEW daily_sales
COMMENT 'Daily sales numbers'
SCHEDULE EVERY 1 DAY
AS SELECT date AS date, sum(sales) AS sumOfSales
FROM table1
GROUP BY date;
-- Sets the runtime channel to "PREVIEW"
> CREATE MATERIALIZED VIEW mv_preview
TBLPROPERTIES(pipelines.channel = "PREVIEW")
AS SELECT * FROM RANGE(10)
-- Create a materialized view with a table constraint
> CREATE MATERIALIZED VIEW IF NOT EXISTS subscribed_movies(
member_id int NOT NULL,
full_name string,
movie_title string,
CONSTRAINT movie_pk PRIMARY KEY(member_id)
)
AS SELECT mo.member_id, mb.full_name, mo.movie_title
FROM movies AS mo INNER JOIN members AS mb ON mo.member_id = mb.id;
-- Create or replace the materialized view to remove the table constraint and add a partition
> CREATE OR REPLACE MATERIALIZED VIEW subscribed_movies
PARTITIONED BY (member_id)
AS SELECT mo.member_id, mb.full_name, mo.movie_title
FROM movies AS mo INNER JOIN members AS mb ON mo.member_id = mb.id;
-- Create a materialized view with a row filter and a column mask
> CREATE MATERIALIZED VIEW masked_view (
id int,
name string,
region string,
ssn string MASK catalog.schema.ssn_mask_fn
)
WITH ROW FILTER catalog.schema.us_filter_fn ON (region)
AS SELECT id, name, region, ssn
FROM employees;