【发布时间】:2019-06-27 06:34:59
【问题描述】:
我们在 BigQuery 中有一个数据湖,它是一个每日分区表(每天有几 TB 的数据)。该表应具有基于由多个字段组成的复合键的唯一标识符。
不时地,我们必须对历史数据进行修改,我们使用DML 进行处理。修改的目标是提供一种修改数据的简单方法,即经济高效且原子。
由于我们的表所具有的架构,挑战出现了。我将用一个例子来说明。请注意,此表未分区,尽管这对于插图而言无关紧要,仅与成本有关。最终解决方案应利用表已分区这一事实。
假设我们有一张表,其架构如下:
还有以下数据:
假设fruit.color 应该使用 DML 语句进行更改。请注意,fruit 是一个可为空 记录,而fruit.type 是必需。
可以使用UPDATE 或MERGE 查询来执行DML。
使用UPDATE
#standardSQL
UPDATE `test_dataset.fruity_table`
SET
fruit.color = 'unknown'
WHERE id in ('1', '2')
很遗憾,UPDATE 语句没有有条件地更新字段的选项。这是必需的,因为上面的查询以Required field fruit.type cannot be null; error in writing field fruit 失败。可以为此使用子查询,但在我们的模式中,可空记录中的必填字段非常常见。因此,我们必须执行多个更新语句,这会破坏原子要求。
使用MERGE
#standardSQL
MERGE `test_dataset.fruity_table` t
USING `test_dataset.fruity_table` s
ON t.id = s.id
WHEN MATCHED AND t.fruit IS NOT NULL
THEN UPDATE SET fruit.color = 'unknown'
WHEN MATCHED AND t.fruit IS NULL
THEN -- do nothing, maybe update some other fields that need to be changed
对于MERGE 语句,很遗憾,我们不得不处理 BigQuery 表中存在重复项的事实。这是MERGE 语句无法处理的事情。它以UPDATE/MERGE must match at most one source row for each target row 失败。
如您所见,我们需要MERGE 查询的粒度,以及UPDATE 查询的灵活性。如果MERGE 只更新所有匹配的记录,这将起作用。
关于如何解决这个问题的任何想法?也许是完全不同的方法?
【问题讨论】:
标签: google-bigquery atomic dml