跳至主内容

SQL 数据类型

info

Apache Druid 支持两种查询语言:Druid SQL 和 原生查询。 本文档介绍 SQL 语言。

Druid将每一列与特定的数据类型相关联。本主题介绍Druid SQL中支持的数据类型。

标准类型

Druid 原生支持以下基本列类型:

  • LONG: 64位有符号整数
  • FLOAT: 32位浮点数
  • DOUBLE: 64位浮点数
  • STRING: UTF-8编码的字符串和字符串数组
  • COMPLEX: 非标准数据类型,例如嵌套JSON、hyperUnique和approxHistogram,以及DataSketches
  • ARRAY: 由任意这些类型组成的数组

Druid将时间戳(包括__time列)视为LONG类型,其值表示自UTC时间1970-01-01 00:00:00以来的毫秒数(不计算闰秒)。因此,Druid中的时间戳不携带任何时区信息,仅表示其所对应的精确时间点。有关时间戳处理的更多信息,请参阅Time functions

下表描述了Druid在执行查询时如何将SQL类型映射到原生类型:

SQL 类型Druid 运行时类型默认值*备注
CHARSTRING''
VARCHARSTRING''Druid STRING columns are reported as VARCHAR. Can include multi-value strings as well.
DECIMALDOUBLE0.0DECIMAL uses floating point, not fixed point math
FLOATFLOAT0.0Druid FLOAT columns are reported as FLOAT
REALDOUBLE0.0
DOUBLEDOUBLE0.0Druid DOUBLE columns are reported as DOUBLE
BOOLEANLONGfalse
TINYINTLONG0
SMALLINTLONG0
INTEGERLONG0
BIGINTLONG0Druid LONG columns (except __time) are reported as BIGINT
TIMESTAMPLONG0, meaning 1970-01-01 00:00:00 UTCDruid's __time column is reported as TIMESTAMP. Casts between string and timestamp types assume standard SQL formatting, such as 2000-01-02 03:04:05, not ISO 8601 formatting. For handling other formats, use one of the time functions.
DATELONG0, meaning 1970-01-01Casting TIMESTAMP to DATE rounds down the timestamp to the nearest day. Casts between string and date types assume standard SQL formatting—for example, 2000-01-02. For handling other formats, use one of the time functions.
ARRAYARRAYNULLDruid native array types work as SQL arrays, and multi-value strings can be converted to arrays. See Arrays for more information.
OTHERCOMPLEXnone可能表示各种Druid列类型,例如hyperUnique、approxHistogram等。

* 所有类型的默认值均为NULL



对于两种SQL类型之间的转换,其行为取决于运行时类型:

  • 在具有相同Druid运行时类型的两种SQL类型之间进行转换时,除了表格中注明的例外情况外,不会产生任何效果。

  • 在两种具有不同Druid运行时类型的SQL类型之间进行转换时,会在Druid中生成运行时转换。

如果值无法转换为目标类型,例如CAST('foo' AS BIGINT),Druid会替换为NULL

数组

Druid支持ARRAY类型,其行为与标准SQL数组一致,结果会通过匹配整个数组进行分组。通过使用UNNEST操作符可以对单个数组元素执行操作,将每个元素转换为单独的行。

ARRAY类型的列可以通过基于JSON的摄取方式存储在段中,使用与模式自动发现共享的'auto'类型维度模式来检测并将数组作为ARRAY类型列摄取。对于基于SQL的摄取,必须将查询上下文参数arrayIngestMode指定为"array"以摄取ARRAY类型。在Druid 28中,为了向后兼容,此参数的默认模式是"mvd",它只能处理ARRAY类型,并将其存储在多值字符串列中。

您可以通过MV_TO_ARRAY显式地将多值维度转换为标准SQL数组,或使用数组函数隐式转换。您还可以使用数组函数从多列构建数组。

Druid默认将ARRAY结果序列化为数组的JSON字符串,这可以通过上下文参数sqlStringifyArrays进行控制。当设置为false并使用JSON结果格式时,数组将以常规JSON数组形式返回,而非字符串化形式。

多值字符串

Druid的原生类型系统允许字符串拥有多个值。这些多值字符串维度在SQL中报告为VARCHAR类型,可以像其他VARCHAR一样在语法上使用。引用多值字符串维度的常规字符串函数会单独应用于每行的所有值。

您可以使用特殊的多值字符串函数将多值字符串维度视为数组,这些函数执行强大的数组感知操作,同时保留其VARCHAR类型和行为。

按多值维度分组遵循Druid原生的多值聚合行为,类似于隐式的SQL UNNEST操作。详见Grouping获取更多信息。

info

由于SQL规划器将多值维度视为VARCHAR类型,因此在Druid SQL和原生查询中对它们的处理方式存在一些不一致。例如,涉及多值维度的表达式可能会被Druid SQL规划器错误优化。比如multi_val_dim = 'a' AND multi_val_dim = 'b'会被优化为false,但实际上单行数据完全可能同时包含'a''b'作为multi_val_dim的值。

多值维度在SQL中的行为可能会在未来的版本中发生变化,以更贴近其在原生查询中的表现,但多值字符串函数应能提供几乎所有可能的原生功能。

多值字符串行为

Druid 多值字符串维度的行为会根据其使用场景而变化。

当与期望每行单个输入值的标准VARCHAR函数(如CONCAT)一起使用时,Druid会将函数映射到行中的所有值。如果行为空或为空,则函数接收NULL作为其输入。

当与显式的多值字符串函数一起使用时,Druid会将行值当作ARRAY类型进行处理。任何产生空行和空值的操作会被区分为不同的值(与隐式映射行为不同)。这些多值字符串函数通常以MV_为前缀,在计算完成后仍保持VARCHAR类型。请注意Druid的多值列不会区分空行和空值。空行永远不会作为原生输入传递给多值函数,但任何操作数组形式值的多值函数都可能产生空数组,这在处理过程中会单独处理。

info

不要在同一表达式中混用多值函数和普通标量函数,因为规划器将无法根据其模糊用法确定如何处理该值。多值字符串在表达式中必须保持一致处理。

当转换为ARRAY或与数组函数一起使用时,多值字符串的行为类似于标准SQL数组,无法再使用非数组函数进行操作。

默认情况下,如果未对值进行分组操作,Druid会将多值VARCHAR结果序列化为数组的JSON字符串。 若值经过分组(由于隐式UNNEST行为),所有结果将始终以标准单值VARCHAR形式呈现。数组类型结果的序列化由上下文参数sqlStringifyArrays控制。当该参数设为false且使用JSON结果格式时,数组将以常规JSON数组形式返回,而非字符串化形式。

NULL值

默认情况下,Druid处理NULL值的方式与ANSI SQL标准类似。

关于空值处理的示例,请参阅空值处理教程

布尔逻辑

Druid在过滤处理和布尔表达式评估中使用SQL三值逻辑

嵌套列

Druid支持使用原生COMPLEX类型在数据段中存储嵌套数据结构。更多信息请参阅Nested columns

您可以使用JSON函数与嵌套数据进行交互,这些函数可以提取嵌套值、从字符串解析、序列化为字符串,并创建新的COMPLEX结构。

COMPLEX类型在专门使用它们的函数之外功能有限,因此在以下情况下其行为未定义:

  • 基于复杂值的分组。
  • 直接对复杂值进行过滤。
  • 用作聚合器的输入,无需针对特定复杂类型进行专门处理。

在许多情况下,提供了将COMPLEX值类型转换为STRING的函数,这是一种临时解决方案,直到COMPLEX类型功能得到改进。