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

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

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

継続的マテリアライズド ビューは、制限付き SQL 構文を使用します。次のパターンは、継続的マテリアライズド ビューの 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 クエリを非同期セカンダリ インデックスとしてビルドする場合は、ORDER BY 句を使用します。

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

from_item:
    {
      table_name [ as_alias ]
      | field_path
      }

as_alias:
    [ AS ] alias

クエリの制限事項

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

  • SELECT ステートメントである必要があります。
  • GROUP BY 句または(非同期セカンダリ インデックス クエリの場合は)ORDER BY 句のいずれかを含める必要があります。両方を含めることはできません。
  • サポートされている集計関数のみを使用する必要があります。
  • グループごとに複数の集計を設定できます。

サポートされている集計

継続的マテリアライズド ビューを定義する 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
  • SELECT *
  • ウィンドウ集計を作成する OVER
  • STRUCT

GROUP BY 句または ORDER 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 句を使用して行を集計するか、ORDER 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 を指定できます。指定しない場合、GROUP BY 句の列がビューのキーを形成します。

_key 列で定義された行キー

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

  • _key でグループ化する必要があります。_timestamp でグループ化することはできますが、それ以外の方法でグループ化することはできません。詳細については、タイムスタンプをご覧ください。
  • _key 列の型は BYTES にする必要があります。

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

GROUP BY 句または ORDER BY 句で定義された行キー

_key を指定しない場合、SELECT リストの集計されていない列がビューの行キーになります。キー列には、SQL 規則でサポートされている任意の名前を割り当てることができます。ReadRows リクエストではなく SQL を使用してビューをクエリする場合は、この方法を使用します。

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

GROUP BY 句ではなく ORDER BY 句を使用して非同期セカンダリ インデックスを作成すると、ORDER BY 句の一部である SELECT リストの列がビューの行キーになります。ORDER BY 句で列が記述される順序は、連続マテリアライズド ビューの行キーにデータが格納される順序です。たとえば、ORDER BY a, b, c は、a ASCb ASCc ASC の順に行キーで並べ替えられたデータを保存します。

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

集計データ

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

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

次に例を示します。

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 でクエリを実行するときには表示されません。

出力で別のタイムスタンプを使用するには、TIMESTAMP 型の列をクエリの SELECT リストに追加して、_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 リファレンスの エンコードをご覧ください。

次のステップ