持续性具体化视图查询
如需创建 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
和其他非确定性函数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 语句
选择子句用于配置持续性具体化视图中使用的列和汇总,并且必须使用 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 一致) |