StarRocks 高精度定点数 DECIMAL 完全指南:从 Fast DECIMAL 到 DECIMAL256
StarRocks 高精度定点数 DECIMAL 完全指南从 Fast DECIMAL 到 DECIMAL256【免费下载链接】starrocksThe worlds fastest open query engine for sub-second analytics both on and off the data lakehouse. With the flexibility to support nearly any scenario, StarRocks provides best-in-class performance for multi-dimensional analytics, real-time analytics, and ad-hoc queries. A Linux Foundation project.项目地址: https://gitcode.com/GitHub_Trending/st/starrocksStarRocks 中的DECIMAL(P[,S])是一种高精度定点数类型用于在金融计算、计费统计、精确测量等对数值精度要求严苛的场景下避免二进制浮点数带来的舍入误差。本文以官方文档 DECIMAL.md 为骨架结合仓库源码与真实建表/插入示例系统讲解 Fast DECIMALDECIMAL32/64/128与 v4.0 起引入的 DECIMAL256 的精度范围、底层存储、类型转换、聚合支持、溢出行为与使用限制读完你即可在 StarRocks 中正确选用合适精度的 DECIMAL 类型并规避溢出陷阱。DECIMAL(P,S) 基本语义DECIMAL(P[,S])中两个参数的含义如下PPrecision有效数字总位数即整数位与小数位之和。SScale小数点后保留的最大位数。参数均有默认值省略P时默认为10省略S时默认为0。例如DECIMAL等价于DECIMAL(10,0)。从版本能力上看StarRocks 将 DECIMAL 的实现划分为两个阶段v4.0 之前支持基于 Fast DECIMAL 的 DECIMAL128即最大精度为 38 位。v4.0 及以后新增 DECIMAL256将精度上限进一步扩展到 76 位。在 BE 端DECIMAL 族类型的逻辑类型LogicalType统一定义在 logical_type.h 中TYPE_DECIMAL32 47、TYPE_DECIMAL64 48、TYPE_DECIMAL128 49、TYPE_DECIMAL256 26而TYPE_DECIMAL16与TYPE_DECIMALV252为历史版本遗留类型。Fast DECIMAL变长整数存储开关与精度范围Fast DECIMAL 由 FE 动态参数enable_decimal_v3控制默认开启。该开关在 FE 配置类 Config.java 中声明public static boolean enable_decimal_v3 true;Fast DECIMAL 模式下P的取值范围为[1, 38]S的取值范围为[0, P]默认值为0。存储策略委托给整数类型Fast DECIMAL 的核心思想是使用变宽整数variable-width integers来表达小数把定点数直接编码进整数从而获得整数运算的极致性能。具体映射关系如下精度范围LogicalType底层存储Delegate LogicalTypeP ≤ 18Decimal64int64BIGINT18 P ≤ 38Decimal128int128LARGEINT这一映射在 BE 端的 logical_type.h 中有直接对应inline constexpr LogicalType DelegateTypeTYPE_DECIMAL32 TYPE_INT; inline constexpr LogicalType DelegateTypeTYPE_DECIMAL64 TYPE_BIGINT; inline constexpr LogicalType DelegateTypeTYPE_DECIMAL128 TYPE_LARGEINT; inline constexpr LogicalType DelegateTypeTYPE_DECIMAL256 TYPE_INT256;也就是说18 位及以内的 DECIMAL 在内存与存储中按 64 位有符号整数处理1938 位则按 128 位整数处理运算时复用原生整型的 SIMD 优化路径。实际完成数值运算与溢出检测的实现集中在 decimalv3.h 与 integer_overflow_arithmetics.h 中。复杂类型中的嵌套支持从 v3.1 起Fast DECIMAL 可作为元素类型嵌套进 ARRAY、MAP 和 STRUCT例如ARRAYDECIMAL(10,2)满足 JSON 半结构化数据中的精确小数处理需求。DECIMAL256扩展到 76 位精度精度上限与容量提升StarRocks 从 v4.0 起引入 DECIMAL256P的取值范围为(38, 76]S的取值范围为[0, P]默认值为0。DECIMAL256 将精度上限从 38 位扩展到 76 位其数值容量是 DECIMAL128 的 10³⁸ 倍从而把运算溢出的概率压到可忽略的程度。它实际可表示的数值范围为-57896044618658097711785492504343953926634992332820282019728792003956564819968 至 57896044618658097711785492504343953926634992332820282019728792003956564819967存储策略DECIMAL256 采用与 Fast DECIMAL 相同的定点数编码策略在既有两种类型之外新增精度范围LogicalType底层存储Delegate LogicalType38 P ≤ 76Decimal256int256INT_256对应 BE 端 logical_type.h 中的TYPE_DECIMAL256 26其存储类型为 256 位整数。类型守卫Type Guard如Decimal128LTGuard、Decimal256LTGuard以及统一的DecimalLTGuard涵盖 DECIMAL32/64/128/256也定义在 logical_type.h用于在模板派发中按类型分派到不同的运算实现。DECIMAL256 的类型转换DECIMAL256 支持与下列所有类型之间的双向类型转换源类型目标类型TYPE_DECIMAL256BOOLTYPE_DECIMAL256TYPE_TINYINT、TYPE_SMALLINT、TYPE_INT、TYPE_BIGINT、TYPE_LARGEINTTYPE_DECIMAL256TYPE_FLOAT、TYPE_DOUBLETYPE_DECIMAL256TYPE_VARCHAR这意味着你可以用CAST(col AS DECIMAL(70,30))将 38 位精度的 DECIMAL128 显式提升为 DECIMAL256将 DECIMAL256 与整数、浮点、字符串类型互转浮点与 DECIMAL256 互转时需注意浮点本身的二进制表示误差将 DECIMAL256 直接与VARCHAR互相转换便于与字符串类型的上下游系统对接。DECIMAL256 支持的聚合函数目前 DECIMAL256 支持以下聚合函数COUNT/COUNT DISTINCTSUM/SUM DISTINCTAVG/AVG DISTINCTMAX/MINABS也就是说DECIMAL256 列可以正常参与计数、求和、平均、极值等常见统计聚合满足大数域上的报表分析需求。DECIMAL256 的使用限制DECIMAL256 目前存在以下三点限制使用时需特别注意1. 不支持运算结果的自动精度提升DECIMAL128 * DECIMAL128不会自动放大为 DECIMAL256。DECIMAL256 只在操作数被显式指定为 DECIMAL256 时才生效有两种途径在CREATE TABLE语句中把列声明为DECIMAL(70,30)这样的 38 位精度类型通过CAST显式转换如SELECT CAST(p38s10 AS DECIMAL(70, 30))。2. 不支持窗口函数DECIMAL256 列不能直接用于OVER (PARTITION BY ...)这类窗口计算需要先降精度或转换类型。3. 聚合表Aggregate Table不支持 DECIMAL256在AGGREGATE KEY模型的表中不能将列声明为 DECIMAL256 类型如需在大数域做聚合应改用明细模型或主键模型或在导入前完成类型规划。实战示例Fast DECIMAL 建表与查询CREATE TABLE decimalDemo ( pk BIGINT(20) NOT NULL COMMENT , account DECIMAL(20,10) COMMENT ) ENGINEOLAP 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 | -----------------------account DECIMAL(20,10)属于 19~38 位精度段底层按 Decimal128 存储。从查询结果可以看到插入的数值被按S10补齐/截断小数位3.141592656显示为3.141592656021.638378显示为21.6383780000这正是定点数按 Scale 定长输出的行为。DECIMAL256 建表与插入行为验证创建包含 DECIMAL256 列的表精度 50、小数位 48CREATE TABLE test_decimal256( p50s48 DECIMAL(50, 48) COMMENT );场景一正常写入INSERT INTO test_decimal256(p50s48) SELECT 1.222222;此语句执行成功值被正确写入。场景二FE 层溢出 → 写入 NULLINSERT INTO test_decimal256(p50s48) SELECT 11111111111111111111111111111111111111111111.222222;此语句执行成功但值被写为NULL。原因该值的整数部分加上按 scale48 展开的小数部分44 位小数后总位数超出了 256 位整数可表示的最大范围FE 直接在解析/校验阶段将该值转成了 NULL。场景三BE 层溢出 → 报错INSERT INTO test_decimal256(p50s48) SELECT 333;此语句返回错误ERROR 1064 (HY000): Insert has filtered data原因整数部分与按 scale48 展开的小数部分之和超出了 50 位整数即DECIMAL(50,48)本身所能表示的最大值BE 在写入阶段判定数据被过滤并返回错误。通过场景二与场景三可以清晰观察到溢出处理的分层行为精度超限在 FE 侧被静默转 NULL类型内表示超限则在 BE 侧报错过滤。使用建议与溢出控制可以通过设置系统变量sql_mode为ERROR_IF_OVERFLOW让系统在发生算术溢出时返回错误而不是 NULL从而避免数据被静默置空造成的精度隐患SET sql_mode ERROR_IF_OVERFLOW;实际生产中建议遵循以下几点按业务量级选精度普通金额/度量用DECIMAL(18,2)一类即可落入 Decimal64 的 int64 快路径需要 19~38 位精度的科学计算与加密场景用 Decimal128只有确认会逼近 38 位上限时才考虑 DECIMAL256。显式声明避免隐式降级由于 DECIMAL256 不做自动精度提升涉及高精度运算时务必在建表或 CAST 中显式声明 38 位精度。监控溢出开启ERROR_IF_OVERFLOW让潜在溢出提前暴露而不是让数据变成 NULL 后悄悄流失。小结StarRocks 的 DECIMAL 体系覆盖了从 32 位到 256 位的完整定点数精度阶梯Fast DECIMAL默认开启的enable_decimal_v3通过委托整型实现高性能的 DECIMAL32/64/128v4.0 引入的 DECIMAL256 则把精度上限推到 76 位配合类型转换、常用聚合与ERROR_IF_OVERFLOW溢出控制能够可靠支撑绝大多数高精度数值计算场景。选型时只需把握一条主线38 位以内优先 Fast DECIMAL逼近上限再显式升级 DECIMAL256并始终留意溢出与窗口函数、聚合表的限制。延伸阅读官方数据类型文档DECIMAL.md半结构化类型中的 DECIMAL 嵌套Array.md、Map.md、STRUCT.mdBE 端类型定义logical_type.hDECIMAL32/64/128/256 逻辑类型与委托类型BE 端运算实现decimalv3.h、integer_overflow_arithmetics.hFE 端开关配置Config.javaenable_decimal_v3 true【免费下载链接】starrocksThe worlds fastest open query engine for sub-second analytics both on and off the data lakehouse. With the flexibility to support nearly any scenario, StarRocks provides best-in-class performance for multi-dimensional analytics, real-time analytics, and ad-hoc queries. A Linux Foundation project.项目地址: https://gitcode.com/GitHub_Trending/st/starrocks创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考