在可空记录中嵌套了必填字段的分区表上的BigQuery DML

时间:2019-06-27 06:34:59

标签: google-bigquery atomic dml

我们在BigQuery中有一个数据湖,它是一个每日分区表(每天有几TB的数据)。该表应具有基于包含多个字段的组合键的唯一标识符。

我们有时不时需要对历史数据进行修改,这些数据是使用DML处理的。修改的目的是要有一种简单的方法来修改数据,既经济高效又

由于表具有的架构,因此出现了挑战。我将使用一个示例进行说明。请注意,该表未分区,尽管这与图示无关,仅是成本。最终解决方案应利用表已分区这一事实。

假设我们有一个具有以下模式的表:

Table schema

以及以下数据:

Table data

让我们说fruit.color应该用DML语句更改。请注意,fruit可空记录,而fruit.type必需

可以使用UPDATEMERGE查询执行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仅更新所有匹配的记录,那么它将起作用。

关于如何解决此问题的任何想法?也许是完全不同的方法?

1 个答案:

答案 0 :(得分:2)

使用UPDATE,而不是SET设置fruit.color,而是SET水果-与您在MERGE中的操作类似。您只需要将MERGE中具有的选项表示为单个表达式即可将水果设置为NULL或带有非NULL必填字段的内容:

update test_dataset.fruity_table
SET fruit = IF(fruit IS NOT NULL, STRUCT('unknown', fruit.type), NULL) 
where id = '3'