Carpe Diem

備忘録

BigQueryのパーティション分割テーブル、日付別テーブル

概要

BigQueryにおける分割テーブルは

  • パーティション分割テーブル
    • 大きな1つのテーブル
  • 日付別テーブル(レガシー)
    • 複数テーブル

の大きく2種類あり、さらにパーティション分割テーブルは

  • 取り込み時間による分割
  • 時間単位カラムによる分割
  • 整数範囲による分割

の3種類あります。

今回はそれらの違い、作成方法、terraformの設定方法を解説します。

パーティション分割テーブル

取り込み時間による分割

データを取り込む時間に基づいて、パーティションに自動的に行を割り当てます。
パーティションの境界は UTC 時間に基づきます。
取り込み時間パーティション分割テーブルには、_PARTITIONTIMEという名前の疑似列が用意されます。

ref: https://cloud.google.com/bigquery/docs/partitioned-tables?hl=ja#ingestion_time

作り方

パーティション設定で「取り込み時間により分割」を選択します。

時間単位列による分割

データの特定のカラム(型がDATETIMESTAMPDATETIMEのどれか)を元にパーティション分割します。
実際のイベント時間と取り込み時間にラグがある場合はこちらが良いでしょう。

作り方

フィールドから選択します。 スキーマには、パーティショニング列に DATETIMESTAMPDATETIME 列を含める必要があります。

整数範囲による分割

年齢など特定のINTEGERカラムを元にパーティション分割します。

時系列的な分割はできないけれど、パーティション分割したい場合に有用です。

作り方

フィールドから選択します。 スキーマにパーティショニング列に対する INTEGER 列が含まれている必要があります。

整数範囲による分割では開始、終了、間隔の値を指定します。

この範囲外の値は、特定の __UNPARTITIONED__ パーティションに入ります。

日付別テーブル

パーティション分割テーブルが提供される前のテーブル分割方法として用意されたものです。今だと使うことはほぼありません。

パーティション分割テーブルの1テーブルあたりのパーティション上限は4000なので、もしそれを超えるケースがあれば採用するのが良いでしょう。

作り方

テーブル名に_yyyymmddサフィックスを付けるだけです。

テーブルとしては独立して存在していますが、

このようにBigQuery UIでまとめてくれます。

Terraformの設定方法

次にTerraformでの設定の違いを説明します。

https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/bigquery_table#nested_time_partitioning

で設定します。

取り込み時間による分割

要素 設定
time_partitioning 設定する
time_partitioning.type 設定する
time_partitioning.field 設定しない
range_partitioning 設定しない
resource "google_bigquery_table" "ingestion" {
  dataset_id = google_bigquery_dataset.main.dataset_id
  table_id   = "ingestion"
  schema     = file("./schema.json")

  time_partitioning {
    type                     = "DAY"
    require_partition_filter = true
  }
}

時間単位列による分割

要素 設定
time_partitioning 設定する
time_partitioning.type 設定する
time_partitioning.field スキーマにおけるTIMESTAMP系のフィールドを指定する
range_partitioning 設定しない
resource "google_bigquery_table" "time_based_column" {
  dataset_id = google_bigquery_dataset.main.dataset_id
  table_id   = "time-based-column"
  schema     = file("./schema.json")

  time_partitioning {
    type                     = "DAY"
    field                    = "time"
    require_partition_filter = true
  }
}

整数範囲による分割

要素 設定
time_partitioning 設定しない
time_partitioning.type 設定しない
time_partitioning.field 設定しない
range_partitioning 設定する
range_partitioning.field スキーマにおけるINTEGERのフィールドを指定する
range_partitioning.range 設定する
resource "google_bigquery_table" "range_based_column" {
  dataset_id = google_bigquery_dataset.main.dataset_id
  table_id   = "range-based-column"
  schema     = file("./range_schema.json")

  range_partitioning {
    field = "age"
    range {
      start    = 0
      end      = 100
      interval = 1
    }
  }
}

参考