持续性具体化视图查询

如需创建 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 子句
  • 必须仅使用受支持的聚合函数
  • 必须定义至少一个汇总列
  • 每个组可以有多个汇总

支持的汇总

您可以在用于定义持续性具体化视图的 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 功能:

  • GoogleSQL for Bigtable 不支持的任何功能
  • 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,则 applebanana 列中包含超过 1 MiB 数据的任何行都会从持续性具体化视图中排除。
  • 从该行输出的数据量超过 1 MiB。当您使用 SELECT REPEAT(apple, 1000) 等查询或使用大型常量时,可能会发生这种情况。
  • 输出的数据量是所选数据量的 10 倍以上。
  • 查询与您的数据不匹配。这包括尝试对零进行除法、整数溢出,或预期行键格式并非在每个行键中都使用。

被排除的行在首次处理时会使“用户错误数”指标递增。如需详细了解可帮助您监控持续性具体化视图的指标,请参阅指标

查询详情

本部分介绍了持续具体化视图查询,以及查询视图时结果可能的显示方式。来源表中的数据是输入,持续性具体化视图中的结果数据是输出。输出数据可以是汇总数据,也可以是未汇总数据(在定义的键中)。

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

如果您打算使用 ReadRows(而非 SQL)读取视图,则指定 _key 非常有用,因为这样您就可以控制行键格式。另一方面,对具有已定义 _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,则输出行的 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 查询视图时不会看到。

如需在输出中使用其他时间戳,您可以向查询的 SELECT 列表中添加一个 TIMESTAMP 类型的列,并将其命名为 _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 NULL 56
4 2024-05-04 00:00:00Z 8 NULL

编码

如果您使用 SQL 查询持续的物化视图,则无需了解汇总值的编码方式,因为 SQL 会将结果显示为类型化列。

如果您使用 ReadRows 从视图读取数据,则需要在读取请求中解码汇总数据。如需详细了解 ReadRows 请求,请参阅读取

连续具体化视图中的汇总值是根据视图定义中列的输出类型,使用下表中所述的编码进行存储。

类型 编码
布尔值 1 字节值,1 = 真,0 = 假
BYTES 无编码
INT64(或 INT、SMALLINT、INTEGER、BIGINT、TINYINT、BYTEINT) 64 位大端字节序
FLOAT64 64 位 IEEE 754,不包括 NaN 和 +/-inf
STRING UTF-8
时间/时间戳 一个 64 位整数,表示自 Unix 纪元起的微秒数(与 GoogleSQL 一致)
如需了解详情,请参阅 Data API 参考文档中的 编码

后续步骤