継続的なマテリアライズド ビュー クエリ
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
などの非確定的関数DATE
、DATETIME
(出力列として。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
順に個別の行に表示されます。 - 指定された
baz
にfoo
が 1 つ以上ある場合、出力行のsum_foo
は NULL 以外の値になります。 - 指定された
baz
にbar
が 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 と一致) |