【问题标题】:Split table into multiple tables based on date using bigquery with a single query for partitioning使用 bigquery 和单个查询进行分区,根据日期将表拆分为多个表
【发布时间】:2017-02-03 18:51:55
【问题描述】:

我想要做的原来的“为什么”是:

恢复一个保持其原始分区的表,而不是全部进入今天的分区。

我想我能做的就是bq load 到一个临时表。然后运行一个查询,按照bq partition 所需的命名约定,即sharded_YYYYMMDD,每天将该表拆分为一个表YYYYMMDD。然后运行bq partition

此页面https://cloud.google.com/bigquery/docs/creating-partitioned-tables 提供了示例,但它需要每天运行一个查询。那可能是数百个:

bq query --use_legacy_sql=false --allow_large_results --replace \ --noflatten_results --destination_table 'mydataset.temps$20160101' \ 'SELECT stn,temp from `bigquery-public-data.noaa_gsod.gsod2016` WHERE mo="01" AND da="01" limit 100'

那么我如何创建一个查询,该查询将遍历所有天并每天创建一个表?

我在这里Split a table into multiple tables in BigQuery SQL 发现了一个类似的问题,但没有关于使用单个查询的答案。

【问题讨论】:

    标签: google-bigquery


    【解决方案1】:

    这里的主要问题是每天都进行全面扫描。其余的问题不大,可以在任何client of your choice 中轻松编写脚本

    那么,以下是 - 如何避免每天进行全表扫描?

    请尝试以下逐步查看方法
    它足够通用,可以扩展/适用于您的实际案例 - 同时我在您的问题中使用与您相同的示例,并且我将锻炼限制在 10 天

    第 1 步 - 创建数据透视表
    在这一步中,我们 a) 将每一行的内容压缩到记录/数组中 b) 将它们全部放入各自的“每日”列中

    #standardSQL
    SELECT
      ARRAY_CONCAT_AGG(CASE WHEN d = 'day20160101' THEN r END) AS day20160101,
      ARRAY_CONCAT_AGG(CASE WHEN d = 'day20160102' THEN r END) AS day20160102,
      ARRAY_CONCAT_AGG(CASE WHEN d = 'day20160103' THEN r END) AS day20160103,
      ARRAY_CONCAT_AGG(CASE WHEN d = 'day20160104' THEN r END) AS day20160104,
      ARRAY_CONCAT_AGG(CASE WHEN d = 'day20160105' THEN r END) AS day20160105,
      ARRAY_CONCAT_AGG(CASE WHEN d = 'day20160106' THEN r END) AS day20160106,
      ARRAY_CONCAT_AGG(CASE WHEN d = 'day20160107' THEN r END) AS day20160107,
      ARRAY_CONCAT_AGG(CASE WHEN d = 'day20160108' THEN r END) AS day20160108,
      ARRAY_CONCAT_AGG(CASE WHEN d = 'day20160109' THEN r END) AS day20160109,
      ARRAY_CONCAT_AGG(CASE WHEN d = 'day20160110' THEN r END) AS day20160110
    FROM (
      SELECT d, r, ROW_NUMBER() OVER(PARTITION BY d) AS line
      FROM (
        SELECT 
          stn, CONCAT('day', year, mo, da) AS d, ARRAY_AGG(t) AS r
        FROM `bigquery-public-data.noaa_gsod.gsod2016` AS t 
        GROUP BY stn, d
      ) 
    )
    GROUP BY line
    

    在 Web UI 中使用 pivot_table(您可以在此处选择所需的任何名称)作为目标运行上述查询

    如您所见 - 在这里我们将获得 10 列的表 - 一天一列,每列的架构是原始表架构的副本:

    第 2 步 – 一个一个地创建分片表,只扫描相应的列(没有全表扫描)

    #standardSQL
    SELECT r.*
    FROM pivot_table, UNNEST(day20160101) AS r
    

    使用名为 mytable_20160101 的目标表从 Web UI 运行上述查询

    你可以在第二天继续运行

    #standardSQL
    SELECT r.*
    FROM pivot_table, UNNEST(day20160102) AS r
    

    现在您应该有名为 mytable_20160102 的目标表,依此类推
    您应该能够使用您选择的任何客户端自动化/编写此步骤 注意:那些最终的每日表格将具有与原始表格完全相同的架构!

    您可以如何使用上述方法有很多变体 - 这取决于您的创造力

    注意:BigQuery 最多允许表中包含 10000 列,因此一年中的相应天数为 365 列绝对不是问题 :o)

    【讨论】:

      【解决方案2】:

      在这里回答自己。我见过的另一种方法是编写一个脚本:

      1. 解析tablebackup.json文件,输出多个文件tablebackuppartitionYYYYMMDD.json在提供的参数上拆分。

      2. 创建一个批处理脚本,将bq load 的所有文件放到相应的表分区中。

      脚本需要逐行或逐块处理才能处理大量备份。并且需要一些时间。使用这种方法的优点是它是通用的并且可供未经培训的 BQ 系统管理员使用。

      【讨论】:

        猜你喜欢
        • 2021-08-21
        • 1970-01-01
        • 1970-01-01
        • 2022-12-22
        • 2016-12-06
        • 2021-01-26
        • 2016-08-24
        • 2018-01-15
        • 2020-04-23
        相关资源
        最近更新 更多