我们在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
仅更新所有匹配的记录,那么它将起作用。
关于如何解决此问题的任何想法?也许是完全不同的方法?
答案 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'