持續性 materialized view 查詢
如要建立 Bigtable 資料表的持續增補 materialized view,請執行定義該檢視的 SQL 查詢。
本文說明相關概念和模式,協助您準備持續增補的 materialized view SQL 查詢。閱讀本文之前,請先熟悉持續具體化檢視區塊和 Bigtable 適用的 GoogleSQL。
持續增補的 materialized view 使用受限的 SQL 語法。以下模式說明如何建構持續增補的 materialized view 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
如要將持續增補的 materialized view 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
查詢限制
下列規則適用於用來建立持續增補 materialized view 的 SQL 查詢:
- 必須是
SELECT陳述式。 - 必須有
GROUP BY子句,或 (針對非同步次要索引查詢)ORDER BY子句,但不得同時有兩者。 - 只能使用支援的匯總函式。
- 每個群組可有多個匯總。
支援的匯總
在定義連續具體化檢視表的 SQL 查詢中,您可以使用下列匯總函式:
COUNTSUMMINMAXHLL_COUNT.INITHLL_COUNT.MERGEHLL_COUNT.MERGE_PARTIALANY_VALUEBIT_ANDBIT_ORBIT_XORAVG
如果 SELECT COUNT(*),您必須定義資料列鍵,如下列範例所示:
SELECT
'*' AS _key,
COUNT(*) AS count
FROM
foo
GROUP BY
_key;
不支援的 SQL 功能
您無法使用下列 SQL 功能:
- Bigtable 的 GoogleSQL 不支援的任何功能
ARRAYARRAY_AGGARRAY_CONCAT_AGGCOUNT_IFCURRENT_TIME和其他非確定性函式DATE、DATETIME做為輸出資料欄 (使用TIMESTAMP或儲存字串)。DESC輸出內容中的排序方式DISTINCT選項,如SUM(*DISTINCT* value)所示)LIMIT/OFFSETSELECT *OVER子句,用於建立視窗匯總STRUCT
您也無法巢狀化 GROUP BY 或 ORDER BY 子句,或建立地圖欄。如需其他限制,請參閱「限制」一節。
避免排除資料列
在下列情況下,輸入資料列會從持續增補的 materialized view 中排除:
- 從資料列選取超過 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 倍以上。
- 查詢內容與資料不符。包括嘗試除以零、整數溢位,或預期使用並非每個資料列索引鍵都採用的資料列索引鍵格式。
系統首次處理排除的資料列時,使用者錯誤指標會增加。如要進一步瞭解可協助您監控持續具體化檢視區塊的指標,請參閱「指標」。
查詢詳細資料
本節說明持續增補的 materialized view 查詢,以及查詢檢視區塊時的結果。來源資料表中的資料是輸入內容,而持續具體化檢視中的結果資料則是輸出內容。輸出資料會經過匯總或未經匯總 (在定義的鍵中)。
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類型。
如果您打算使用 ReadRows (而非 SQL) 讀取檢視區塊,指定 _key 就很有用,因為這樣您就能控管資料列鍵格式。另一方面,如果檢視表的 SQL 查詢已定義 _key,可能需要明確解碼 _key,而不是只傳回結構化鍵欄。
由 GROUP BY 或 ORDER BY 子句定義的資料列索引鍵
如未指定 _key,SELECT 清單中未匯總的資料欄就會成為檢視畫面中的資料列鍵。您可以為索引鍵資料欄指派 SQL 慣例支援的任何名稱。如果您打算使用 SQL 查詢檢視表,而非 ReadRows 請求,請採用這種做法。
SELECT 清單中的非匯總輸出資料欄必須包含在 GROUP
BY 子句中。GROUP BY 子句中寫入資料欄的順序,就是資料在連續具體化檢視資料列鍵中儲存的順序。舉例來說,GROUP BY a, b, c 會隱含 ORDER BY a ASC, b ASC, c
ASC。
如果您使用 ORDER BY 子句 (而非 GROUP BY 子句) 建立非同步次要索引,SELECT 清單中屬於 ORDER BY 子句的資料欄會成為檢視區塊中的資料列鍵。ORDER BY 子句中寫入資料欄的順序,就是資料在連續具體化檢視資料列鍵中儲存的順序。舉例來說,ORDER BY a, b, c 會依序以 a ASC、b ASC 和 c 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順序顯示在不同資料列中。 - 如果指定
baz至少有一個foo,則輸出資料列的sum_foo為非 NULL 值。 - 如果指定
baz至少有一個bar,則輸出資料列的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,必須大於或等於零,且必須是 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 | 空值 | 56 |
| 4 | 2024-05-04 00:00:00Z | 8 | 空值 |
編碼
如果您使用 SQL 查詢持續增補的 materialized view,則不需要瞭解匯總值的編碼方式,因為 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 | 64 位元整數,代表自 Unix 紀元起算的微秒數 (與 GoogleSQL 一致) |