查询 Avro 数据
借助 GoogleSQL for Bigtable,您可以查询、过滤和投影 Bigtable 表存储的序列化 Apache Avro 记录中的各个字段。通过在 SQL 查询中引用 Avro 架构包,您可以将字节列转换为结构化 Avro 记录并提取嵌套字段。
在查询 Avro 字段之前,您必须在架构包中上传 Avro 架构,如创建和管理 Avro 架构中所述。如需了解 GoogleSQL 查询如何映射到 Bigtable 表架构,以及如何在 SQL 语句中引用列,请参阅 GoogleSQL for Bigtable 概览。
如需在 Java 中使用 GoogleSQL 查询 Avro 数据,请使用 Cloud Bigtable 客户端库中的 executeQuery 方法。如需查看使用客户端库运行 SQL 查询的示例,请参阅客户端库。
Avro 数据类型映射
将序列化 BYTES 转换为 Avro 记录时,GoogleSQL for Bigtable 会将 Avro 架构类型映射到 SQL 可访问的类型,如下所示:
| Avro 类型 | GoogleSQL 表示法 | 说明 |
|---|---|---|
int,long |
INT64 |
32 位和 64 位有符号整数会映射到 64 位整数。 |
float |
FLOAT32 |
单精度浮点值 |
double |
FLOAT64 |
双精度浮点值 |
boolean |
BOOL |
布尔值(TRUE 或 FALSE) |
string |
STRING |
Unicode 字符序列 |
bytes |
BYTES |
原始字节序列 |
record |
消息对象 | 使用点表示法(例如 record.field)访问嵌套字段。 |
enum |
ENUM |
枚举符号集 |
array |
ARRAY |
重复字段。Bigtable 不支持嵌套数组。 |
map<T> |
键值对条目重复 | Avro 映射具有 STRING 键。Bigtable 支持具有可为 null 的值的映射,例如 {"type": "map", "values": ["null", "string"]}。您可以使用 ARRAY_TRANSFORM 函数将映射转换为 ARRAY<STRUCT<key STRING, value T>>。 |
union |
可以为 Null 的字段 | Bigtable 会将包含 null 和一个非 null 类型的联合映射到标准可为 null 的字段。 |
fixed |
Bigtable 不支持 fixed 类型。 |
固定长度的字节序列。 |
示例数据
本页中的示例使用 ID 为 my_avro 的 Avro 架构包。此软件包在 com.example.billing 命名空间中包含以下 Transaction 记录架构:
{
"type": "record",
"namespace": "com.example.billing",
"name": "Transaction",
"fields": [
{"name": "product_name", "type": "string"},
{"name": "product_category", "type": "string"},
{"name": "configs", "type": {"type": "map", "values": "string"}}
]
}
名为 table 的 Bigtable 表将序列化的 Avro 记录存储在 cf 列族和 product 列限定符 (cf['product']) 中:
| 行键 | cf['product'] 列(存储为序列化 BYTES,为便于阅读,显示为 JSON) |
|---|---|
row1 |
{"product_name": "Chips", "product_category": "yummy food", "configs": {"size": "large", "flavor": "BBQ"}} |
row2 |
{"product_name": "Apple", "product_category": "yummy food", "configs": {}} |
row3 |
{"product_name": "Book", "product_category": "reading", "configs": {"author": "Jane Doe"}} |
示例查询
上传 Avro 架构软件包后,您可以在 GoogleSQL for Bigtable 中使用 CAST 运算符将 BYTES 值解释为 Avro 记录。
转换列和投影字段
如需将 BYTES 值转换为 Avro 记录,请按以下格式指定完整记录名称:
SCHEMA_BUNDLE_ID.FULLY_QUALIFIED_RECORD_NAME
替换以下内容:
SCHEMA_BUNDLE_ID:架构包的 IDFULLY_QUALIFIED_RECORD_NAME:Avro 记录的全名,包括 Avro 架构中定义的命名空间,例如com.example.billing.Transaction
如果指定的架构包或记录名称不存在,则查询会失败,并显示 INVALID_ARGUMENT 状态和 type not found 出错提示。如果提供的架构无法解析单元格字节,则查询会失败,并显示 FAILED_PRECONDITION 或 INVALID_ARGUMENT 状态。
以下查询会将 cf['product'] 列转换为 my_avro 架构包中的 com.example.billing.Transaction 记录,并投影 product_name 字段:
SELECT
CAST(cf['product'] AS my_avro.com.example.billing.Transaction).product_name
FROM
table;
查询将返回以下结果:
product_name (STRING) |
|---|
| 芯片数 |
| Apple |
| 书籍 |
根据 Avro 字段进行过滤
您可以使用 WHERE 子句根据 Avro 记录中的字段值过滤行。
以下查询会过滤 product_category 字段等于 "yummy food" 的行:
SELECT
CAST(cf['product'] AS my_avro.com.example.billing.Transaction).product_name
FROM
table
WHERE
CAST(cf['product'] AS my_avro.com.example.billing.Transaction).product_category = "yummy food";
查询将返回以下结果:
product_name (STRING) |
|---|
| 芯片数 |
| Apple |
访问映射字段
您可以使用 ARRAY_TRANSFORM 函数将 Avro map 字段中的键值对投影为 STRUCT 元素数组。
以下查询会投影 product_name,并将 configs 映射字段转换为 STRUCT<key STRING, value STRING> 元素数组:
SELECT
CAST(cf['product'] AS my_avro.com.example.billing.Transaction).product_name,
ARRAY_TRANSFORM(
CAST(cf['product'] AS my_avro.com.example.billing.Transaction).configs,
e -> STRUCT(e.key, e.value)
) AS map_array
FROM
table;
查询将返回以下结果:
product_name (STRING) |
map_array (ARRAY<STRUCT<key STRING, value STRING>>) |
|---|---|
| 芯片数 | [{"key": "size", "value": "large"}, {"key": "flavor", "value": "BBQ"}] |
| Apple | [] |
| 书籍 | [{"key": "author", "value": "Jane Doe"}] |
与视图搭配使用
如果持续具体化视图或逻辑视图引用了 Avro 架构包,则您无法删除该包。在删除该 bundle 之前,您必须先删除引用该 bundle 的所有持续物化视图。对于引用该 bundle 的任何逻辑视图,您必须更新这些视图以移除引用,或者删除这些视图。
以下命令会创建一个持续具体化视图,用于按 product_name 汇总交易计数:
gcloud bigtable materialized-views create MATERIALIZED_VIEW_ID \
--instance=INSTANCE_ID \
--query="SELECT CAST(cf['product'] AS my_avro.com.example.billing.Transaction).product_name AS product, COUNT(*) AS transaction_count FROM table GROUP BY product;"
替换以下内容:
MATERIALIZED_VIEW_ID:引用架构包的持续具体化视图的 IDINSTANCE_ID:Bigtable 实例的 ID
后续步骤
- 了解如何创建和管理 Avro 架构。
- 了解如何查询 protobuf 数据。
- 阅读架构设计最佳实践。