变体与 JSON 字符串有何不同?
重要
此功能目前以公共预览版提供。
本文介绍使用变体数据类型时的行为变化以及语法和语义的差异。 本文假设你知道如何在 Azure Databricks 上处理 JSON 字符串数据。 对于 Azure Databricks 的新用户,在存储需要灵活更改或未知架构的半结构化数据时,应使用 JSON 字符串的变体。 请参阅对半结构化数据建模。
在 Databricks Runtime 15.3 及更高版本中,可以使用变体数据类型来编码和查询半结构化数据。 Databricks 建议使用变体来替代使用 JSON 字符串存储半结构化数据的做法。 变体的读写性能提高使其能够在某些用例中取代原生的 Spark 复杂类型,例如结构和数组。
如何查询变体数据?
变体数据使用相同的运算符来查询字段、子字段和数组元素。
若要查询某个字段,请使用 :
。 例如 column_name:field_name
。
若要查询某个子字段,请使用 .
。 例如 column_name:field_name.subfield_name
。
若要查询数组元素,请使用 [n]
,其中 n
是元素的整数索引值。 例如,若要查询数组中的第一个值,请使用 column_name:array_name[0]
。
从 JSON 字符串升级到变体时,以下差异可能会破坏现有查询:
- 所有变体路径元素均以区分大小写的方式进行匹配。 JSON 字符串不区分大小写。 这意味着,对于变体,
column_name:FIELD_NAME
和column_name:field_name
在存储的数据中查找不同的字段。 [*]
语法不支持识别或解包数组中的所有元素。- 变体以不同于 JSON 字符串的方式对
NULL
值进行编码。 请参阅变量 null 规则。
在 JSON 字符串与变体之间来回转换
在 Databricks Runtime 15.3 及更高版本中,to_json
函数具有将 VARIANT
类型强制转换为 JSON 字符串的附加功能。 将 VARIANT
转换为 JSON 字符串时,将忽略选项。 请参阅 to_json。
parse_json
函数将 JSON 字符串转换为 VARIANT
类型。 虽然 parse_json(json_string_column)
是 to_json(variant_column)
的逻辑反函数,但以下转换规则描述了为什么它不是确切的反函数:
- 空白字符不会完美保留。
- 键的排序是任意的。
- 可能会截断数字中的尾随零。
如果 JSON 字符串格式不正确或超出变体大小限制,则 parse_json
函数将返回错误。 如果在分析过程中出现错误,则使用 try_parse_json
函数返回 NULL
。
用于处理变体的 SQL 函数有哪些?
Databricks Runtime 15.3 及更高版本中提供的 Apache Spark SQL 函数提供了与变体数据交互的方法。 下表包括新函数、对应的 JSON 字符串函数以及行为差异的说明。
注意
若要将这些函数与 PySpark 数据帧一起使用,请从 pyspark.sql.functions
导入它们。 PySpark 不支持 variant_explode
和 variant_explode_outer
。
变体函数 | JSON 字符串函数 | 备注 |
---|---|---|
variant_get | cast 和 get_json_object | 采用表达式、路径和类型。 遵循变体路径、强制转换和 null 值的所有规则。 |
try_variant_get | try_cast 和 get_json_object | 采用表达式、路径和类型。 遵循变体路径、强制转换和 null 值的所有规则。 |
is_variant_null | is null | 检查表达式是否存储了 VARIANT 编码的 NULL 。 使用 is null 检查输入表达式是否为 NULL 。 |
schema_of_variant | schema_of_json | 确定 ARRAY<elementType> 的架构时,如果在数据中发现冲突的类型,则 elementType 可能被推理为 VARIANT 。 |
schema_of_variant_agg | schema_of_json_agg | 未识别到最不常用的类型时,类型将派生为 VARIANT 。 |
variant_explode | explode | 输出 pos 、key 和 value 列。 当分解数组时,输出键始终为 null。 |
variant_explode_outer | explode_outer | 输出 pos 、key 和 value 列。 当分解数组时,输出键始终为 null。 |
变体以不同于 JSON 字符串的方式处理强制转换和 NULL
。 请参阅变体类型强制转换规则和变体 null 规则。