复杂类型
表可以包含复杂类型的列,包括嵌套的复杂类型。您可以在原生和外部表(包括 Flex 表)中使用 ROW (结构体)、ARRAY 和 SET 类型。集合仅限于标量类型的一维集合。可用于外部表的 MAP 类型有限,但您可以改用 ARRAY 和 ROW 来表示映射。选定的解析器支持加载具有复杂类型的数据。
您可以为 ARRAY 和 ROW 类型的异构组合定义列:包含数组字段的结构体或结构体数组。这些类型可以嵌套的最大嵌套深度为 100。
原生表存在的限制
原生表中使用的复杂类型除了其参考页面上列出的个别类型的限制外,还有一些限制:
-
原生表必须至少有一个基本类型或原生数组(基本类型的一维数组)的列。如果一个 Flex 表有真实的列,它也必须至少有一个满足这个限制的列。
-
复杂类型列不能在 ORDER BY 或 PARTITION BY 子句中使用,也不能用作 FILLER 列。
-
复杂类型列不能有 约束。
-
返回复杂类型的表达式不能用作投影列,并且投影不能按复杂类型的列进行分段或排序。
-
具有复杂类型列的表不能使用 DEFAULT 和 SET USING。
有关其他限制,请参阅 CREATE TABLE 和 ALTER TABLE。
从数据派生表定义
可以使用 INFER_TABLE_DDL 函数检查 Parquet、ORC、JSON 或 Avro 数据,并为表定义生成一个起点。此函数返回 CREATE TABLE 语句,它可能需要进一步编辑。对于函数无法推断数据类型的列,该函数会将类型标记为未知并发出警告。对于 VARCHAR 和 VARBINARY 列,可能需要调整长度。请始终查看函数返回的语句,但特别是对于具有很多列的表,使用该函数可以节省时间和精力。
Parquet、ORC 和 Avro 文件包含架构信息,但 JSON 文件并不包含。对于 JSON,该函数检查原始数据以生成一个或多个候选表定义。在以下示例中,两个输入文件的菜单列结构不同:
=> SELECT INFER_TABLE_DDL ('/data/*.json'
USING PARAMETERS table_name='restaurants', format='json',
max_files=3, max_candidates=3);
WARNING 0: This generated statement contains one or more float types which might lose precision
WARNING 0: This generated statement contains one or more varchar/varbinary types which default to length 80
INFER_TABLE_DDL
------------------------------------------------------------------------
Candidate matched 1/2 of total files(s):
create table "restaurants"(
"cuisine" varchar,
"location_city" Array[varchar],
"menu" Array[Row(
"item" varchar,
"price" float
)],
"name" varchar
);
Candidate matched 1/2 of total files(s):
create table "restaurants"(
"cuisine" varchar,
"location_city" Array[varchar],
"menu" Array[Row(
"items" Array[Row(
"item" varchar,
"price" numeric
)],
"time" varchar
)],
"name" varchar
);
(1 row)
强类型的替代方案
尽管您可以完全指定表示 ROW 和 ARRAY 类型的任意组合的列,但在某些情况下您可能更喜欢更灵活的方法。如果数据包含具有数百个字段的结构体,而您只需要其中几个字段,则您可能更愿意在查询时仅提取这几个字段,而不是定义所有字段。同样,如果数据结构可能发生更改,您可能更愿意推迟完全指定复杂类型。您可以使用可变列来替代完全指定复杂列的结构。这与用于 Flex 表的方法相同,该表中的所有数据最初都会加载到一个二进制列中,然后根据需要从该位置实体化。有关使用此方法的详细信息,请参阅可变复杂类型。