持續性 materialized view 查詢

如要建立 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

查詢限制

下列規則適用於用來建立持續性 materialized view 的 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 BYORDER BY 子句,或是建立地圖資料欄。如需其他限制,請參閱「限制」一節。

避免排除的資料列

在下列情況下,輸入資料列會從持續性 materialized view 中排除:

  • 從資料列選取超過 1 MiB 的資料。舉例來說,如果查詢是 SELECT apple AS apples , SUM(banana) AS sum_bananas FROM my_table GROUP BY apples,則 applebanana 資料欄中含有超過 1 MiB 資料的任何資料列,都會從連續具體化檢視區塊中排除。
  • 資料列輸出超過 1 MiB 的資料。使用 SELECT REPEAT(apple, 1000) 等查詢或大型常數時,可能會發生這種情況。
  • 輸出資料量是所選資料量的 10 倍以上。
  • 查詢與資料不符。包括嘗試除以零、整數溢位,或預期使用並非每個資料列索引鍵都採用的資料列索引鍵格式。

系統首次處理排除的資料列時,使用者錯誤指標會增加。如要進一步瞭解可協助您監控持續具體化檢視區塊的指標,請參閱「指標」。

查詢詳細資料

本節說明持續性具體化檢視查詢,以及查詢檢視區塊時的結果可能樣貌。來源資料表中的資料是輸入內容,而持續具體化檢視中的結果資料則是輸出內容。輸出資料會經過匯總或未經匯總 (在定義的鍵中)。

SELECT 陳述式

選取陳述式會設定連續具體化檢視表使用的資料欄和匯總。陳述式必須使用 GROUP BY 子句來彙整資料列,或使用 ORDER BY 子句建立全域次要索引。

系統不支援 SELECT *,但支援 SELECT COUNT(*)

如同一般 SELECT 陳述式,您可以在一組分組資料中進行多項匯總作業。未分組的資料欄必須是匯總結果。

以下是標準 GROUP BY SQL 匯總查詢的範例:

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 BYORDER BY 子句定義的資料列索引鍵

如未指定 _keySELECT 清單中未匯總的資料欄就會成為檢視畫面中的資料列鍵。您可以為鍵資料欄指派 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 為非空值。
  • 如果指定 baz 至少有一個 bar,則輸出資料列的 sum_bar 為非空值。
  • 如果指定 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 查詢持續性具體化檢視區塊,則不需要瞭解匯總值的編碼方式,因為 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 一致)
詳情請參閱 Data API 參考資料中的「 編碼」。

後續步驟