增量表简介
Dataform 会根据表类型以不同的方式更新表。在每次执行表或视图时,Dataform 都会从头开始重新构建整个表或视图。
定义增量表时,Dataform 仅在首次构建增量表时从头开始构建。在后续执行期间,Dataform 仅根据您配置的条件将新行插入或合并到增量表中。
Dataform 仅将新行插入增量表中已存在的列。如果您更改增量表定义查询(例如添加新列),则必须从头开始重新构建表。为此,请在下次触发表的执行时,选择运行并完全刷新选项。
以下是增量表的一些常见用例:
- 性能优化
- 对于某些类型的数据(例如网站日志或分析数据),您可能只想处理新记录,而不是重新处理整个表。
- 缩短延迟时间
- 您可以使用增量表快速但频繁地执行工作流,从而缩短输出表的下游延迟时间。
- 每日快照
- 您可以配置增量表来创建表数据的每日快照,例如,对存储在生产数据库中的用户设置进行纵向分析。
准备工作
所需的角色
如需获得配置增量表所需的权限,请让您的管理员为您授予工作区的 Dataform Editor (roles/dataform.editor
) IAM 角色。
如需详细了解如何授予角色,请参阅管理对项目、文件夹和组织的访问权限。
处理增量表中的部分行
如需确定 Dataform 在每次执行期间要处理的行子集,请向增量表 SQLX 定义文件添加条件 WHERE
子句。在 WHERE
子句中,您可以指定增量条件和非增量条件。在表格执行期间,如果不进行完整刷新,Dataform 会应用增量条件;如果进行完整刷新,则会应用非增量条件。
如需配置增量表,请按以下步骤操作:
- 前往您的开发工作区。
- 在文件窗格中,展开
definitions/
。 - 打开增量表定义 SQLX 文件。
按以下格式输入
WHERE
子句:config { type: "incremental" } SELECT_STATEMENT ${when(incremental(), `WHERE INCREMENTAL_CONDITION`, `WHERE NON_INCREMENTAL_CONDITION`) }
替换以下内容:
- SELECT_STATEMENT:用于定义表的
SELECT
语句 INCREMENTAL_CONDITION:您在
WHERE
子句中指定的条件,用于在表格执行期间选择要由 Dataform 处理的行,而无需完全刷新。NON_INCREMENTAL_CONDITION:您在
WHERE
子句中指定的条件,用于在表执行期间通过完全刷新选择要由 Dataform 处理的行。
- SELECT_STATEMENT:用于定义表的
可选:点击格式。
以下代码示例展示了一个增量表,该表会增量处理 productiondb.logs
表的行:
config { type: "incremental" }
SELECT timestamp, message FROM ${ref("productiondb", "logs")}
${when(incremental(),
`WHERE date > (SELECT MAX(date) FROM ${self()}) AND country = "UK"`,
`WHERE country = "UK"`)}
以下代码示例展示了一个增量表,该表会创建 productiondb.customers
表的快照:
config { type: "incremental" }
SELECT CURRENT_DATE() AS snapshot_date, customer_id, name, account_settings FROM ${ref("productiondb", "customers")}
${when(incremental(), `WHERE snapshot_date > (SELECT MAX(snapshot_date) FROM ${self()})`) }
合并增量表中的行
为确保增量表仅包含与所选列组合对应的一行,请将所选列设置为 uniqueKey
,以合并具有相同 uniqueKey
的行。更新表时,Dataform 会使用 uniqueKey
合并行,而不是附加行。
如需在增量表中配置合并,请按以下步骤操作:
- 前往您的开发工作区。
- 在文件窗格中,展开
definitions/
。 - 选择增量表定义 SQLX 文件
在
config
代码块中,将所选列设置为uniqueKey
,格式如下:uniqueKey: ["COLUMN_NAME"]
将 COLUMN_NAME 替换为所选列的名称。
可选:点击格式。
以下代码示例展示了一个增量表,其中 transaction_id
列设置为 uniqueKey
,以确保该列始终包含一行:
config {
type: "incremental",
uniqueKey: ["transaction_id"]
}
SELECT timestamp, action FROM weblogs.user_actions
${ when(incremental(), `WHERE timestamp > (SELECT MAX(timestamp) FROM ${self()})`) }
过滤增量表中的行
在增量分区表中,为避免 Dataform 扫描整个表以查找匹配的行,请将 updatePartitionFilter
设置为仅考虑部分记录。
以下代码示例展示了一个增量分区表,其中通过设置 uniqueKey
和 updatePartitionFilter
属性配置了合并:
config {
type: "incremental",
uniqueKey: ["transaction_id"],
bigquery: {
partitionBy: "DATE(timestamp)",
updatePartitionFilter:
"timestamp >= timestamp_sub(current_timestamp(), interval 24 hour)"
}
}
SELECT timestamp, action FROM weblogs.user_actions
${ when(incremental(), `WHERE timestamp > (SELECT MAX(timestamp) FROM ${self()})`) }
从分区表中提取数据时,避免全表扫描
创建引用分区表的增量表时,我们建议您构建表查询,以避免在每次增量更新期间对分区表进行全表扫描。
您可以在表查询中使用常量表达式,限制 BigQuery 扫描的分区数量,以更新增量表。如需将分区表中的值转换为常量表达式,请使用 BigQuery 脚本在 pre_operations
块中将该值声明为变量。然后,在 SELECT
查询的 WHERE
子句中将该变量用作常量表达式。
采用此配置后,Dataform 会根据引用的分区表的最新分区更新增量表,而无需扫描整个表。
如需配置引用分区表并避免全表扫描的增量表,请按以下步骤操作:
- 前往您的开发工作区。
- 在文件窗格中,展开
definitions/
。 - 选择增量表定义 SQLX 文件
- 在
pre_operations
块中,使用 BigQuery 脚本声明变量。 - 使用引用声明的变量的
WHERE
子句过滤用于定义表的SELECT
语句。 - 可选:点击格式。
以下代码示例展示了一个增量表,其中引用的 raw_events
表按 event_timestamp
分区:
config {
type: "incremental",
}
pre_operations {
DECLARE event_timestamp_checkpoint DEFAULT (
${when(incremental(),
`SELECT max(event_timestamp) FROM ${self()}`,
`SELECT timestamp("2000-01-01")`)}
)
}
SELECT
*
FROM
${ref("raw_events")}
WHERE event_timestamp > event_timestamp_checkpoint
在前面的代码示例中,event_timestamp_checkpoint
变量是在 pre_operations
块中定义的。然后,event_timestamp_checkpoint
变量会在 WHERE
子句中用作常量表达式。
通过完全刷新从头重建增量表
您可以使用命令行界面(并使用 --full-refresh
选项)或触发工作流执行时使用“Run with full refresh”(在完全刷新的情况下运行)选项,强制从头重新构建增量表。
在开发工作区中或使用 Dataform CLI 选择“完全刷新”选项时,Dataform 会在执行期间忽略 ${when(incremental(), ... }
参数,并使用 CREATE OR REPLACE
语句重新创建表。
保护增量表免遭全面刷新
为防止增量表从头重建并可能丢失数据,您可以将增量表设置为 protected
。如果您的数据源是临时的,您可能需要阻止重新构建增量表。
如需将增量表标记为 protected
,请按以下步骤操作:
- 前往您的开发工作区。
- 在文件窗格中,展开
definitions/
。 - 选择增量表定义 SQLX 文件。
- 在
config
代码块中,输入protected: true
。 - 可选:点击格式。
以下代码示例展示了一个标记为 protected
的增量表:
config {
type: "incremental",
protected: true
}
SELECT ...
后续步骤
- 如需了解如何定义表,请参阅创建表。
- 如需了解如何使用 Dataform 命令行界面,请参阅使用 Dataform CLI。
- 如需了解如何手动触发执行,请参阅触发执行。