创建动态表¶
本主题概述了创建动态表的关键概念。
开始之前,请确保您 有权创建动态表,并且动态表查询使用的所有对象都启用了 更改跟踪。
创建动态表时存在一些限制。有关完整列表,请参阅 动态表限制。
备注
有关编写可高效使用增量刷新的查询的指南,请参阅 优化增量刷新查询。
启用更改跟踪¶
在创建具有增量刷新模式的动态表时,如果尚未对其查询的表启用更改跟踪,Snowflake 会自动尝试对其启用更改跟踪。为支持增量刷新,必须对动态表使用的所有基础对象启用 非零 Time Travel 保留 的更改跟踪。
随着基础对象的变化,动态表也会发生变化。如果您重新创建一个基础对象,您必须重新启用更改跟踪。
备注
Snowflake 不会自动尝试在使用完全刷新模式创建的动态表上启用更改跟踪。
要对特定数据库对象启用更改跟踪,请在该对象上使用 ALTER TABLE、ALTER VIEW 和类似命令。创建动态表的用户必须具有 OWNERSHIP 权限,才能对所有基础对象启用更改跟踪。
要检查是否启用了更改跟踪,请在基础对象上使用 SHOW VIEWS、SHOW TABLES 和类似命令,并检查 change_tracking 列。
支持的基础对象¶
动态表支持以下基础对象:
表
Snowflake 管理的 Apache Iceberg™ 表
外部管理的 Apache Iceberg™ 表
示例:创建简单的动态表¶
假设您要创建一个动态表,该表包含来自名称为 staging_table 的表的 product_id 和 product_name 列,并且您决定:
您希望动态表中的数据最多比
staging_table中的数据滞后 20 分钟。您希望将仓库
mywh用于 刷新 所需的计算资源。您希望自动选择刷新模式。
Snowflake 建议仅在开发期间使用自动刷新模式。有关更多信息,请参阅 选择刷新模式。
您希望动态表在创建时同步刷新。
您希望自动选择刷新模式,并希望动态表在创建时同步刷新。
要创建此动态表,请执行以下 CREATE DYNAMIC TABLE SQL 语句:
CREATE OR REPLACE DYNAMIC TABLE my_dynamic_table
TARGET_LAG = '20 minutes'
WAREHOUSE = mywh
REFRESH_MODE = auto
INITIALIZE = on_create
AS
SELECT product_id, product_name FROM staging_table;
有关参数和变体语法的完整列表,请参阅 CREATE DYNAMIC TABLE 参考。
从 Snowflake 管理或外部管理的 Apache Iceberg™ 表创建动态表¶
从 Iceberg 表创建动态表与从普通表创建类似。可以像为普通表创建动态表一样,执行 CREATE DYNAMIC TABLE SQL 语句,将 Snowflake 管理的表或外部目录管理的表作为基础对象。
如果动态表以 Snowflake 管理的 Iceberg 表作为基表,则在以下情况下非常有用:希望您的数据管道操作基于 Snowflake 管理的 Iceberg 表中的数据,或者希望管道操作由其他引擎写入的 Iceberg 表。需要注意的是,外部引擎无法写入 Snowflake 管理的 Iceberg 表;对于 Snowflake 来说,它们是可读写的,而对于外部引擎则是只读的。
如果动态表以 外部(非 Snowflake)目录 管理的 Iceberg 表为基础(例如 AWS 管理、由 Apache Spark 等引擎写入),则适用于处理外部数据湖中的数据。您可以在外部管理的数据之上创建动态表,并在 Snowflake 中持续处理数据,而无需复制或导入数据。
使用 Iceberg 表的限制和注意事项¶
常规动态表 和 动态 Iceberg 表 的所有限制仍然适用。
此外:
Iceberg 基表的所有限制均适用。有关更多信息,请参阅 注意事项和限制。
您可以创建动态表,读取 Snowflake 原生表、Snowflake 管理的 Iceberg 表以及外部管理的 Iceberg 表。
对于外部管理的 Iceberg 基表,动态表以文件级别跟踪变化,而其他基表以行级别跟踪变化。在外部管理的 Iceberg 表上频繁执行写入复制操作(例如更新或删除)可能会影响增量刷新性能。
创建具有不可变性和回填功能的动态表¶
不可变性约束 允许您将动态表的某些部分标记为静态。当您定义 IMMUTABLE WHERE 子句时,Snowflake 会在刷新期间跳过这些行,从而提高具有大量历史数据的表的性能。
通过允许您将现有数据复制到动态表中而无需对其进行计算,回填扩展了不可变性约束。此操作使历史数据立即可用,同时您可以为将来的更新定义自定义刷新查询。
有关详细信息和示例,请参阅 使用不可变性约束。
创建动态表的最佳实践¶
将动态表的管道链接在一起¶
定义新的动态表时,不要定义包含许多嵌套语句的大型动态表,而应使用小型动态表与管道组合的方式。
您可以设置动态表来查询其他动态表。例如,想象这样一个场景:您的数据管道从暂存表中提取数据以更新各种维度表(例如,customer、product、date 和 time)。此外,管道还根据这些维度表中的信息更新汇总 sales 表。通过将维度表配置为查询暂存表,将汇总 sales 表配置为查询维度表,可以创建类似于任务图的级联效果。
在此设置中,仅在维度表刷新成功完成后才能执行汇总 sales 表的刷新。这样可以确保数据的一致性并达到滞后目标。通过自动刷新过程,源表中的任何更改都会在适当的时候触发对所有从属表的刷新。
对复杂任务图使用“控制器”动态表¶
如果您有一个动态表的复杂图表,其中包含许多根节点和叶节点,并且您想使用单个命令对整个任务图执行操作(例如更改滞后、手动刷新、挂起),请执行以下步骤:
将所有动态表的
TARGET_LAG值设置为DOWNSTREAM。创建一个“控制器”动态表,从任务图中的所有叶中读取。
叶动态表是任务图中没有下游依赖项的节点。没有其他动态表从中读取,因此它不是任何其他动态表的依赖项。
将
<leaf1>、<leaf2>、...、<leafN>替换为实际的叶动态表名称。要确保此控制器不消耗资源,请使用
LIMIT 0创建笛卡尔联接。
CREATE DYNAMIC TABLE controller TARGET_LAG = <target_lag> WAREHOUSE = <warehouse> AS SELECT 1 A FROM <leaf1>, …, <leafN> LIMIT 0;
使用此控制器控制整个图表。例如:
为任务图设置新的目标滞后。
ALTER DYNAMIC TABLE controller SET TARGET_LAG = <new_target_lag>;手动刷新任务图。
ALTER DYNAMIC TABLE controller REFRESH;
使用瞬态动态表降低存储成本¶
瞬态 动态表可随着时间的推移可靠地维护数据,并支持数据保留期内的 Time Travel,但不保留超过故障安全期的数据。默认情况下,动态表数据在 故障安全 存储中保留七天。
对于具有高刷新吞吐量的动态表,这会显著增加存储消耗。因此,只有当动态表的数据不需要与永久表提供的数据保护和恢复处于相同级别时,才应将其变为瞬态表。
您可以使用 CREATE DYNAMIC TABLE 语句创建瞬态动态表,或将现有动态表克隆到瞬态动态表。
动态表创建故障排除¶
创建动态表时,初始刷新要么按计划 (ON_SCHEDULE) 进行,要么在创建时立即进行 (ON_CREATE)。初始数据填充或 初始化 取决于此初始刷新发生的时间。例如,对于 ON_CREATE,如果初始化触发上游动态表刷新,则可能需要更长时间。
初始化可能需要一些时间,具体取决于扫描的数据量。要查看进度,请执行以下操作:
登录 Snowsight。
在导航菜单中,选择 Monitoring » Query History。
在 Filters 下拉列表中,在 SQL Text 筛选器中输入 CREATE DYNAMIC TABLE,并在 Warehouse 筛选器中输入您的仓库名称。
选择 SQL text 下动态表的查询,并使用 Query Details 和 Query Profile 选项卡跟踪进度。