⌘+k ctrl+k
1.3 (稳定版)
搜索快捷键 cmd + k | ctrl + k
数值类型

整数类型

类型 TINYINTSMALLINTINTEGERBIGINTHUGEINT 存储各种范围的整数,即不带小数部分的数字。尝试存储超出允许范围的值将导致错误。类型 UTINYINTUSMALLINTUINTEGERUBIGINTUHUGEINT 存储无符号整数。尝试存储负数或超出允许范围的值将导致错误。

名称 别名 最小值 最大值 字节大小
TINYINT INT1 - 2^7 2^7 - 1 1
SMALLINT INT2, INT16, SHORT - 2^15 2^15 - 1 2
INTEGER INT4, INT32, INT, SIGNED - 2^31 2^31 - 1 4
BIGINT INT8, INT64, LONG - 2^63 2^63 - 1 8
HUGEINT INT128 - 2^127 2^127 - 1 16
UTINYINT UINT8 0 2^8 - 1 1
USMALLINT UINT16 0 2^16 - 1 2
UINTEGER UINT32 0 2^32 - 1 4
UBIGINT UINT64 0 2^64 - 1 8
UHUGEINT UINT128 0 2^128 - 1 16

整数类型是常见的选择,因为它在范围、存储大小和性能之间提供了最佳平衡。SMALLINT 类型通常仅在磁盘空间非常宝贵时使用。BIGINTHUGEINT 类型旨在用于整数类型范围不足的情况。

可变整数

前面提到的整数类型都有一个共同点,即最小值和最大值范围内的数字都具有相同的存储大小,UTINYINT 为 1 字节,SMALLINT 为 2 字节等。但有时您需要比 HUGEINT 支持的数字更大的数字!对于这些情况,VARINT 类型会派上用场,因为 VARINT 类型具有大得多的限制(该值最多可包含 1,262,612 位数字)。VARINT 的最小存储大小为 4 字节,每位数字占用一个额外位,向上取整到 8(12 位占用 12 位,向上取整到 16,变为两个额外字节)。

VARINT 类型支持负值和正值。

定点小数

数据类型 DECIMAL(WIDTH, SCALE)(也可用别名 NUMERIC(WIDTH, SCALE))表示一个精确的定点小数。创建 DECIMAL 类型的值时,可以指定 WIDTHSCALE 来定义字段中可以存储的小数值大小。WIDTH 字段确定可以容纳多少位数字,scale 确定小数点后的位数。例如,类型 DECIMAL(3, 2) 可以容纳值 1.23,但不能容纳值 12.3 或值 1.234。如果未指定,默认的 WIDTHSCALEDECIMAL(18, 3)

两个定点小数的加法、减法和乘法会返回另一个定点小数,其 WIDTHSCALE 满足包含精确结果的要求,如果所需的 WIDTH 超过当前支持的最大 WIDTH(目前为 38),则会抛出错误。

定点小数的除法通常不会产生有限小数位数的数字。因此,DuckDB 对所有涉及定点小数的除法都使用近似浮点运算,并相应地返回浮点数据类型。

在内部,小数根据其指定的 WIDTH 表示为整数。

宽度 内部 大小(字节)
1-4 INT16 2
5-9 INT32 4
10-18 INT64 8
19-38 INT128 16

在不需要的情况下使用过大的小数可能会影响性能。特别是宽度超过 19 的小数,其运算速度会很慢,因为涉及 INT128 类型的算术运算比涉及 INT32INT64 类型的运算昂贵得多。因此,建议将 WIDTH 保持在 18 或以下,除非有充分的理由说明这不足够。

浮点类型

数据类型 FLOATDOUBLE 精度是可变精度的数值类型。在实践中,这些类型通常是 IEEE 标准 754 二进制浮点算术(分别为单精度和双精度)的实现,具体取决于底层处理器、操作系统和编译器的支持程度。

名称 别名 描述
FLOAT FLOAT4, REAL 单精度浮点数(4 字节)
DOUBLE FLOAT8 双精度浮点数(8 字节)

与定点数据类型类似,从字面量转换或从其他数据类型转换为浮点类型时,无法精确表示的输入将存储为近似值。然而,更难预测哪些输入会受到影响。例如,1.3::DECIMAL(1, 0) - 0.7::DECIMAL(1, 0) != 0.6::DECIMAL(1, 0) 并不令人惊讶,但 1.3::FLOAT - 0.7::FLOAT != 0.6::FLOAT 可能会令人惊讶。

此外,虽然定点小数数据类型的乘法、加法和减法是精确的,但这些运算在浮点二进制数据类型上仅是近似的。

然而,对于更复杂的数学运算,内部使用浮点算术,如果中间步骤转换为与输入和输出相同宽度的定点格式,则可以获得更精确的结果。例如,(10::FLOAT / 3::FLOAT)::FLOAT * 3 = 10,而 (10::DECIMAL(18, 3) / 3::DECIMAL(18, 3))::DECIMAL(18, 3) * 3 = 9.999

总的来说,我们建议:

  • 如果您需要精确存储具有已知小数位数的数字,并且需要精确的加法、减法和乘法(例如对于货币金额),请使用 DECIMAL 数据类型或其 NUMERIC 别名。
  • 如果您想进行快速或复杂的计算,浮点数据类型可能更合适。但是,如果您将结果用于任何重要用途,则应仔细评估您的实现中的边缘情况(范围、无穷大、下溢、无效操作),这些情况的处理方式可能与您预期不同,并且您应该熟悉常见的浮点陷阱。David Goldberg 的文章 “每个计算机科学家都应该了解的浮点算术”Bruce Dawson 博客上的浮点系列提供了很好的起点。

在大多数平台上,FLOAT 类型的范围至少为 1E-37 到 1E+37,精度至少为 6 位小数。DOUBLE 类型的范围通常约为 1E-307 到 1E+308,精度至少为 15 位。超出这些范围的正数(以及超出镜像范围的负数)在某些平台上可能会导致错误,但通常会分别转换为零或无穷大。

除了普通数值之外,浮点类型还有几个表示 IEEE 754 特殊值的特殊值:

  • Infinity: 无穷大
  • -Infinity: 负无穷大
  • NaN: 非数字

在具有所需 CPU/FPU 支持的机器上,DuckDB 遵循 IEEE 754 规范中关于这些特殊值的规定,但有两个例外:

  • NaNNaN 比较相等,并大于任何其他浮点数。
  • 某些浮点函数,如 sqrt / sin / asin,对于超出其定义范围的值会抛出错误,而不是返回 NaN

要将这些值作为字面量插入 SQL 命令中,您必须给它们加上引号,您可以将 Infinity 缩写为 Inf,并且可以使用任何大小写。例如:

SELECT
    sqrt(2) > '-inf',
    'nan' > sqrt(2);
(sqrt(2) > '-inf') ('nan' > sqrt(2))
true true

通用唯一标识符(UUID

DuckDB 通过 UUID 类型支持通用唯一标识符 (UUID)。这些标识符使用 128 位,并在内部表示为 HUGEINT 值。打印时,它们以小写十六进制字符显示,并用连字符分隔,如下所示:12345678-1234-1234-1234-1234567890ab(总共 36 个字符,包括连字符)。例如,4ac7a9e9-607c-4c8a-84f3-843f0191e3fd 是一个有效的 UUID。

DuckDB 支持生成 UUIDv4 和 UUIDv7 标识符。要检索 UUID 值的版本,请使用 uuid_extract_version 函数

UUIDv4

要生成 UUIDv4 值,请使用 uuid() 函数或其别名 uuidv4()gen_random_uuid() 函数。

UUIDv7

要生成 UUIDv7 值,请使用 uuidv7() 函数。要从 UUIDv7 值中检索时间戳,请使用 uuid_extract_timestamp 函数

SELECT uuid_extract_timestamp(uuidv7()) AS ts;
ts
2025-04-19 15:51:20.07+00

函数

参阅数值函数和运算符