【问题标题】:UPSERT BigQueryUPSERT BigQuery
【发布时间】:2020-02-13 23:51:30
【问题描述】:

我有一个 40 列的 Bigqury 表。我想使用 PHP 代码向它插入数据。我将数据插入到数组数组中,如下所示。

[
  0 => array:2 [
    "id" => 1
    "name" => "updated name 1 "
  ]
  1 => array:2 [
    "id" => 3
    "name" => "new name to insert"
  ]
]

我发现在这个post中,存在一个MERGE命令。 我尝试过这样的事情。

MERGE dataset.table c
USING (SELECT * FROM UNNEST([(1, 'updated name 1'),
                             (3, 'new name to insert')])) d
ON c.id = d.id
WHEN NOT MATCHED THEN
  INSERT ROW
WHEN MATCHED THEN
  UPDATE SET c.name = d.name;

这失败了,如何将数据动态填充到 d 中? 该数组可能需要的列数据很少。

我也提到了this

【问题讨论】:

    标签: php google-bigquery


    【解决方案1】:

    您当然可以对部分列执行 UPSERT(只要这些“忽略”列是 NULLABLE,这是默认值),请参阅下面使用临时表的示例来演示该想法:

    CREATE TEMP TABLE c AS 
      SELECT 1 id, "old name" name, NULL col1, NULL col2, NULL col3, NULL col4;
    
    SELECT * FROM c; -- output before
    
    MERGE c
    USING UNNEST([struct<id INT64, name STRING>
                  (1, 'updated name 1'),
                  (3, 'new name to insert')]) d
    ON c.id = d.id
    WHEN NOT MATCHED THEN
      INSERT (id, name) VALUES (d.id, d.name)
    WHEN MATCHED THEN
      UPDATE SET c.name = d.name;
    
    SELECT * FROM c; -- output after
    

    合并前的输出

    +----+----------+------+------+------+------+
    | id |   name   | col1 | col2 | col3 | col4 |
    +----+----------+------+------+------+------+
    |  1 | old name | NULL | NULL | NULL | NULL |
    +----+----------+------+------+------+------+
    

    合并后的输出

    +----+--------------------+------+------+------+------+
    | id |        name        | col1 | col2 | col3 | col4 |
    +----+--------------------+------+------+------+------+
    |  3 | new name to insert | NULL | NULL | NULL | NULL |
    |  1 | updated name 1     | NULL | NULL | NULL | NULL |
    +----+--------------------+------+------+------+------+
    

    警告

    您的查询受长度限制。所以不要在一个查询中 UPSERT 太多行。

    最大未解析的标准 SQL 查询长度 - 1 MB

    我还建议您使用query parameter 来传递您的数据,而不是将它们放入查询中。

    可扩展性

    如果每日更新量超过 200MB,则可能将数据分解成太多 MERGE 使其更接近达到 DML 每日限制。

    每个表每天的最大组合 INSERT、UPDATE、DELETE 和 MERGE 语句数 - 1,000

    您应该考虑其他方式来执行 UPSERT。其中一种方法是将 csv/json/parquet 文件上传到 GCS 并将 load 上传到 BigQuery 表,然后从表中执行类似的 MERGE 语句。

    【讨论】:

    • 非常感谢!你知道我应该把这个发送到 BQ 的哪个端点吗?
    • 我提供的是一个查询,就像你的问题一样,我不确定你指的是什么“端点”。另外,我添加了“可扩展性”部分,希望对您有所帮助。
    猜你喜欢
    • 2021-02-25
    • 1970-01-01
    • 2019-01-28
    • 1970-01-01
    • 2018-08-07
    • 2016-10-01
    • 1970-01-01
    • 2021-12-14
    • 2010-11-11
    相关资源
    最近更新 更多