継続的なマテリアライズド ビュー クエリ

Bigtable テーブルの継続マテリアライズド ビューを作成するには、継続マテリアライズド ビューを定義する SQL クエリを実行します。

このドキュメントでは、継続的なマテリアライズド ビューの SQL クエリを準備する際に役立つコンセプトとパターンについて説明します。このドキュメントを読む前に、継続マテリアライズド ビューBigtable 用の GoogleSQL について理解しておく必要があります。

継続マテリアライズド ビューは、制限付き SQL 構文を使用します。クエリで次のパターンを使用する必要があります。

SELECT
  expression AS alias [, ...]
FROM from_item
[ WHERE bool_expression ]
GROUP BY expression [, ...]

from_item:
    {
      table_name [ as_alias ]
      | field_path
      }

as_alias:
    [ AS ] alias

クエリの制限事項

継続的なマテリアライズド ビューの作成に使用される SQL クエリには、次のルールが適用されます。

  • SELECT ステートメントである必要があります
  • GROUP BY 句が必要です
  • サポートされている集計関数のみを使用する必要があります
  • 集計列を 1 つ以上定義する必要があります
  • グループごとに複数の集計を使用できる

サポートされている集計

継続マテリアライズド ビューを定義する SQL クエリでは、次の集計関数を使用できます。

  • COUNT
  • SUM
  • MIN
  • MAX
  • HLL_COUNT.INIT
  • HLL_COUNT.MERGE
  • HLL_COUNT.MERGE_PARTIAL
  • ANY_VALUE
  • BIT_AND
  • BIT_OR
  • BIT_XOR
  • AVG

SELECT COUNT(*) の場合は、次の例のように行キーを定義する必要があります。

SELECT
  '*' AS _key,
  COUNT(*) AS count
FROM
  foo
GROUP BY
  _key;

サポートされていない SQL 機能

次の SQL 機能は使用できません。

  • Bigtable 向けの GoogleSQL でサポートされていない機能
  • ARRAY
  • ARRAY_AGG
  • ARRAY_CONCAT_AGG
  • COUNT_IF
  • CURRENT_TIME などの非確定的関数
  • DATEDATETIME(出力列として。TIMESTAMP を使用するか、文字列を格納します)。
  • DESC 出力の並べ替え
  • DISTINCT オプション(SUM(*DISTINCT* value) など)
  • LIMIT/OFFSET
  • ORDER BY
  • SELECT *
  • ウィンドウ アグリゲーションを作成する OVER
  • STRUCT

また、GROUP BY 句をネストしたり、マップ列を作成したりすることもできません。その他の制限事項については、制限事項をご覧ください。

除外行を回避する

次の状況では、入力行が継続マテリアライズド ビューから除外されます。

  • 行から 1 MiB を超えるデータが選択されている。たとえば、クエリが SELECT apple AS apples , SUM(banana) AS sum_bananas FROM my_table GROUP BY apples の場合、apple 列と banana 列に 1 MiB を超えるデータを含む行は、連続マテリアライズド ビューから除外されます。
  • 行から 1 MiB を超えるデータが出力されます。これは、SELECT REPEAT(apple, 1000) などのクエリを使用している場合や、大きな定数を使用している場合に発生することがあります。
  • 選択したデータの 10 倍を超えるデータが出力される。
  • クエリがデータと一致しません。これには、ゼロの除算、整数のオーバーフロー、すべての行キーで使用されていない行キー形式の想定が含まれます。

除外された行は、最初に処理されたときにユーザー エラー指標を増分します。継続的なマテリアライズド ビューのモニタリングに役立つ指標の詳細については、指標をご覧ください。

クエリの詳細

このセクションでは、継続的なマテリアライズド ビュー クエリと、ビューに対してクエリを実行した場合の結果の例について説明します。ソーステーブルのデータが入力で、継続マテリアライズド ビューの結果データが出力です。出力データは、集計または未集計(定義されたキー内)のいずれかです。

SELECT ステートメント

select 句は、継続マテリアライズド ビューで使用される列と集計を構成します。GROUP BY 句を使用する必要があります。

SELECT * はサポートされていませんが、SELECT COUNT(*) はサポートされています。

一般的な SELECT ステートメントと同様に、グループ化されたデータセットごとに複数の集計を使用できます。グループ化されていない列は集計結果である必要があります。

SQL の標準 GROUP BY 集計クエリの例を次に示します。

SELECT
  myfamily["node"] AS node,
  myfamily["type"] AS type,
  COUNT(clicks) AS clicks_per_key
FROM
  mytable
GROUP BY
  node,
  type

行キーと未集計データ

必要に応じて、連続マテリアライズド ビューを定義する場合と同様に、_key 出力列を指定できます。これは、Bigtable テーブルに対して SQL クエリを実行したときに取得される _keyとは異なります。_key を指定する場合、次のルールが適用されます。

  • _key でグループ化する必要があります。_timestamp を除き、他の項目でグループ化することはできません(省略可)。詳細については、タイムスタンプをご覧ください。
  • _key 列の型は BYTES にする必要があります。

_key を指定すると、行キーの形式を制御できるため、SQL ではなく ReadRows でビューを読み取る予定がある場合に便利です。一方、_key が定義されているビューに対する SQL クエリでは、構造化キー列を返すだけでなく、_key を明示的にデコードする必要がある場合があります。

_key を使用していない場合は、SELECT ステートメントの集計されていない列が連続マテリアライズド ビューのキーになります。キー列には、SQL 規則でサポートされている任意の名前を割り当てることができます。

SQL フィルタでは、エラーの原因となる可能性のある NULL などの無効な値を除外する必要があります。無効な行は結果から除外されますが、materialized_view/user_errors 指標にはカウントされます。ユーザーエラーをデバッグするには、継続的マテリアライズド ビューの外部で SQL クエリを実行してみてください。

集計されていない出力列は GROUP BY 句に含める必要があります。GROUP BY 句で列が書き込まれる順序は、継続マテリアライズド ビューの行キーにデータが保存される順序です。たとえば、GROUP BY a, b, c は暗黙的に ORDER BY a ASC, b ASC, c ASC です。

集計データ

クエリの集計列は、継続マテリアライズド ビューでデータを生成する計算を定義します。

集計列のエイリアスは、継続マテリアライズド ビューの列修飾子として扱われます。

次に例を示します。

SELECT
  fam["baz"] AS baz,
  SUM(fam["foo"]) AS sum_foo,
  SUM(fam["bar"]) AS sum_bar
FROM
  TABLE
GROUP BY
  baz;

クエリの出力には次の特徴があります。

  • baz の出力は、baz ASC 順に個別の行に表示されます。
  • 指定された bazfoo が 1 つ以上ある場合、出力行の sum_foo は NULL 以外の値になります。
  • 指定された bazbar が 1 つ以上ある場合、出力行の sum_bar は NULL 以外の値になります。
  • 特定の baz のどちらの列にも値がない場合、その baz は結果から除外されます。

SELECT * でビューをクエリすると、結果は次のようになります。

baz sum_foo sum_bar
baz1 sum_foo1 sum_bar1
baz2 sum_foo2 sum_bar2

タイムスタンプ

継続マテリアライズド ビューの出力セルのデフォルトのタイムスタンプは 0(1970-01-01 00:00:00Z)です。これは、ReadRows でビューを読み取ったときに表示されますが、SQL でクエリを実行したときには表示されません。

出力で別のタイムスタンプを使用するには、クエリの SELECT リストに TIMESTAMP タイプの列を追加し、名前を _timestamp にします。ReadRows を使用して継続的マテリアライズド ビューにクエリを実行すると、_timestamp が行内の他のセルのタイムスタンプになります。

タイムスタンプは NULL ではなく、0 以上で、1,000 の倍数(ミリ秒の精度)である必要があります。Bigtable は、Unix エポック(1970-01-01T00:00:00Z)より前のセル タイムスタンプをサポートしていません。

集計データを日単位で再サンプリングする次の例について考えてみましょう。このクエリでは、UNPACK 関数を使用しています。

SELECT
  _key,
  TIMESTAMP_TRUNC(_timestamp, DAY) AS _timestamp,
  SUM(sum_family["sum_column"]) AS sum_column,
  SUM(sum_family["foo"]) AS second_sum_column
FROM
  UNPACK(
  SELECT
    *
  FROM
    my_table(with_history => TRUE))
GROUP BY
  1,
  2

特定の SUM に特定の日付の空でない入力がある場合、出力行には、切り捨てられた日付に一致するタイムスタンプを持つ集計値が含まれます。

SELECT * を使用してビューをクエリすると、結果は次のようになります。

_key _timestamp sum_column second_sum_column
1 2024-05-01 00:00:00Z 23 99
2 2024-05-02 00:00:00Z 45 201
3 2024-05-03 00:00:00Z NULL 56
4 2024-05-04 00:00:00Z 8 NULL

エンコード

SQL で継続マテリアライズド ビューに対してクエリを実行する場合、SQL は結果を型付き列として公開するため、集計値がどのようにエンコードされているかを意識する必要はありません。

ReadRows を使用してビューから読み取る場合は、読み取りリクエストで集計データをデコードする必要があります。ReadRows リクエストの詳細については、読み取りをご覧ください。

連続マテリアライズド ビューの集計値は、ビュー定義の列の出力タイプに基づいて、次の表に示すエンコードを使用して保存されます。

エンコード
BOOL 1 バイトの値。1 = true、0 = false
BYTES エンコードなし
INT64(または INT、SMALLINT、INTEGER、BIGINT、TINYINT、BYTEINT) 64 ビット ビッグ エンディアン
FLOAT64 64 ビット IEEE 754(NaN と +/-inf を除く)
STRING UTF-8
TIME/TIMESTAMP Unix エポックからのマイクロ秒数を表す 64 ビットの整数(GoogleSQL と一致)
詳細については、Data API リファレンスの エンコードをご覧ください。

次のステップ