【问题标题】:BigQuery DML on partitioned table with nested required fields in nullable records分区表上的 BigQuery DML,在可空记录中具有嵌套的必填字段
【发布时间】:2019-06-27 06:34:59
【问题描述】:

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

不时地,我们必须对历史数据进行修改,我们使用DML 进行处理。修改的目标是提供一种修改数据的简单方法,即经济高效且原子

由于我们的表所具有的架构,挑战出现了。我将用一个例子来说明。请注意,此表未分区,尽管这对于插图而言无关紧要,仅与成本有关。最终解决方案应利用表已分区这一事实。

假设我们有一张表,其架构如下:

还有以下数据:

假设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 只更新所有匹配的记录,这将起作用。

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

【问题讨论】:

    标签: google-bigquery atomic dml


    【解决方案1】:

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

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

    【讨论】:

    • 感谢您的回复迈克尔!然而问题是,我不想在表中放置任何虚拟数据。我将更新合并的查询,因为这不清楚。如果fruit 为空,我不想对fruit.color 做任何事情。
    • 我更新了MERGE 查询。现在是否清楚可能需要更改其他一些字段?我想让 MVP 尽可能小以说明问题。
    • 我认为你仍然可以使用这种方法,只是改变表达式计算结果。它必须生成 NULL 结构或具有非 NULL 类型的东西,因为需要类型,所以无法绕过它。例如:SET fruit = IF(fruit IS NOT NULL, STRUCT('unknown',fruit.type), NULL)
    • 结合你的评论和上面的更新查询,这似乎就是我要找的!我还将对其进行测试以验证更复杂的用例。您能否也使用评论中的输入来更新您的原始帖子?然后当我接受答案时它就完成了:)
    猜你喜欢
    • 2019-05-02
    • 1970-01-01
    • 2017-05-29
    • 1970-01-01
    • 2019-05-13
    • 1970-01-01
    • 2020-08-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多