跳到主要内容
版本:Candidate-4.0

DECIMAL

DECIMAL(P[,S]) 是一种高精度定点数值。P 代表有效数字的总数(精度,Precision)。S 代表小数点后的最大位数(刻度,Scale)。

如果省略 P,则默认值为 10。如果省略 S,则默认值为 0。

  • 对于 v4.0 之前的版本,StarRocks 支持基于 Fast DECIMAL 的 DECIMAL128。
  • 对于 v4.0 及更高版本,StarRocks 支持 DECIMAL256

功能

Fast DECIMAL

由 FE 动态参数 enable_decimal_v3 控制,Fast DECIMAL 默认启用。

对于 Fast DECIMAL,P 的范围是 [1,38],S 的范围是 [0, P]。S 的默认值是 0。

Fast DECIMAL 使用可变宽度整数来表示小数。

  • Decimal(P ≤ 18, S)

    • LogicalType:Decimal64
    • 存储格式:int64
    • Delegate LogicalType:BIGINT
  • Decimal(P > 18 & P ≤ 38, S)

    • LogicalType:Decimal128
    • 存储格式:int128
    • Delegate LogicalType:LARGEINT

从 v3.1 开始,StarRocks 支持在 ARRAYMAPSTRUCT 中使用 Fast Decimal 类型。

DECIMAL256

StarRocks 从 v4.0 开始引入 DECIMAL256。

对于 DECIMAL256,P 的范围是 (38,76],S 的范围是 [0, P]。S 的默认值是 0。

DECIMAL256 将精度的上限扩展到 76 位。其数值容量是 DECIMAL128 的 10³⁸ 倍,极大地降低了溢出的概率。

DECIMAL256 使用与 Fast DECIMAL 相同的策略来表示小数。除了上述两种小数类型外,它还支持:

  • Decimal(P > 38 & P ≤ 76, S)
    • LogicalType:Decimal256
    • 存储格式:int256
    • Delegate LogicalType:INT_256

DECIMAL256 的实际可表示范围是 -5789604461865809771178549250434395392663499233282028201972879200395656481996857896044618658097711785492504343953926634992332820282019728792003956564819967

类型转换操作

DECIMAL256 支持与下列所有类型之间的双向类型转换:

源类型目标类型
TYPE_DECIMAL256BOOL
TYPE_DECIMAL256TYPE_TINYINT, TYPE_SMALLINT, TYPE_INT, TYPE_BIGINT, TYPE_LARGEINT
TYPE_DECIMAL256TYPE_FLOAT, TYPE_DOUBLE
TYPE_DECIMAL256TYPE_VARCHAR

聚合函数

目前,DECIMAL256 支持以下聚合函数:COUNTCOUNT DISTINCTSUMSUM DISTINCTAVGAVG DISTINCTMAXMINABS

限制

DECIMAL256 有以下限制:

  • 目前,DECIMAL256 不支持小数运算的自动精度提升。

    例如,DECIMAL128 * DECIMAL128 不会自动提升为 DECIMAL256。DECIMAL256 的特性仅在 DECIMAL256 被明确指定为操作数时应用,无论是在 CREATE TABLE 语句中还是使用 CAST(SELECT CAST(p38s10 as DECIMAL(70, 30)))。

  • DECIMAL256 不支持窗口函数。

  • 聚合表不支持 DECIMAL256 类型。

示例

Fast DECIMAL 示例

在创建表时定义 DECIMAL 列。

CREATE TABLE decimalDemo (
pk BIGINT(20) NOT NULL COMMENT "",
account DECIMAL(20,10) COMMENT ""
) ENGINE=OLAP
DUPLICATE KEY(pk)
COMMENT "OLAP"
DISTRIBUTED BY HASH(pk);

INSERT INTO decimalDemo VALUES
(1,3.141592656),
(2,21.638378),
(3,4873.6293048479);

SELECT * FROM decimalDemo;
+------+-----------------+
| pk | account |
+------+-----------------+
| 1 | 3.1415926560 |
| 3 | 4873.6293048479 |
| 2 | 21.6383780000 |
+------+-----------------+

DECIMAL256 示例

创建一个包含 DECIMAL256 类型列的表。

CREATE TABLE test_decimal256(
p50s48 DECIMAL(50, 48) COMMENT ""
);

插入不同的值:

INSERT INTO test_decimal256(p50s48) SELECT 1.222222;

此语句成功执行,值被正确写入。

INSERT INTO test_decimal256(p50s48) SELECT 11111111111111111111111111111111111111111111.222222;

此语句成功执行,值被写为 NULL。因为整数部分和小数部分(有 44 位数字)与指定的刻度(即 48)一起超过了 256 位整数可表示的最大值,FE 直接将值转换为 NULL。

INSERT INTO test_decimal256(p50s48) SELECT 333;

此语句将返回错误 ERROR 1064 (HY000): Insert has filtered data。因为整数部分和小数部分与指定的刻度(即 48)一起超过了 50 位整数可表示的最大值,BE 返回错误。

注意事项

您可以将系统变量 sql_mode 设置为 ERROR_IF_OVERFLOW,以便在算术溢出时让系统返回错误而不是 NULL。

关键词

decimal, decimalv3, fast decimal, decimal128, decimal256