ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

StarRocks FLOAT 数据类型详解:4 字节单精度浮点的存储、精度与实战用法

2026/9/17 21:01:27 拓冰建站 浏览量
StarRocks FLOAT 数据类型详解:4 字节单精度浮点的存储、精度与实战用法 StarRocks FLOAT 数据类型详解4 字节单精度浮点的存储、精度与实战用法【免费下载链接】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/starrocksFLOAT 是 StarRocks 中用于存储单精度浮点数的 4 字节数值类型适用于对存储开销敏感、对精度要求不苛刻的度量场景如传感器读数、粗略比例、评分等。本文以官方文档 FLOAT.md 为核心结合 FE/BE 源码深入剖析 FLOAT 的底层存储实现、精度行为及与 DOUBLE、DECIMAL 的选型差异帮助读者在建表、写入与查询中正确使用这一类型。FLOAT 是什么FLOAT 是 StarRocks 内置的单精度single-precision浮点数据类型采用 IEEE 754 标准在底层以 4 字节32 bit二进制表示。官方文档 FLOAT.md 对它的定义只有一句4-byte floating point number——4 字节浮点数其有效十进制数字精度约为7 位。与它相对的是 8 字节的 DOUBLE后者的有效精度约为 15 位详见 DOUBLE.md。两者在 StarRocks 中都属于近似数值类型approximate numeric type它们以二进制指数-尾数形式存储无法精确表示所有十进制小数因此在进行等值比较、去重、聚合求和等操作时需要特别留意精度问题。FLOAT 的基本用法建表时定义 FLOAT 列在CREATE TABLE中直接使用FLOAT关键字声明列即可无需指定精度或小数位参数。以下示例完整来自官方文档 FLOAT.md创建一个包含 FLOAT 列的 OLAP 表CREATE TABLE floatDemo ( pk BIGINT(20) NOT NULL, channel FLOAT COMMENT 4 bytes ) ENGINEOLAP DUPLICATE KEY(pk) DISTRIBUTED BY HASH(pk) BUCKETS 1;channel FLOAT声明一个 4 字节的单精度浮点列DUPLICATE KEY(pk)使用明细模型允许同一pk下存在多行DISTRIBUTED BY HASH(pk) BUCKETS 1按pk哈希分桶单桶便于演示。写入与查询向表中插入一个具有 17 位有效数字的小数INSERT INTO floatDemo VALUES (1, 12345.67890123456789);随后查询返回结果如下MySQL SELECT * FROM floatDemo; ----------------- | pk | channel | ----------------- | 1 | 12345.679 | -----------------可以看到写入的12345.67890123456789读出来变成了12345.679——这正是 FLOAT 只有约 7 位有效十进制数字的直接体现超出精度范围的位被舍入rounding处理而不是被丢弃报错。精度行为深度解读为什么 12345.67890123456789 变成 12345.679要理解上述现象需要回到 IEEE 754 单精度浮点的存储结构。32 位 FLOAT 由三部分组成组成部分位数作用符号位sign1 bit表示正负指数位exponent8 bit表示量级2 的幂次尾数位mantissa / significand23 bit表示有效数字23 位尾数加上隐含的 1 位实际可精确表达的二进制有效位约 24 位换算成十进制大约是7 位有效数字log₁₀ 2²⁴ ≈ 7.22。因此在展示12345.67890123456789时StarRocks 保留约 7 位有效数字并四舍五入为12345.679。一个常见误区是FLOAT 能存到小数点后多少位准确的说法应该是FLOAT 能保证多少位有效数字significant digits。有效数字既包含整数部分也包含小数部分对于1.23456789FLOAT 可保留约 7 位小数对于12345678.9由于整数部分已占 8 位小数部分基本无法保留数值越大整数位占用越多可保留的小数位越少。如果业务需要精确的小数运算如金额、汇率应改用 DECIMAL.md 高精度定点类型而不是 FLOAT/DOUBLE。从源码看 FLOAT 的底层实现FE 侧类型注册与词法解析在前端FE中FLOAT 被定义为PrimitiveType枚举的一个实例并显式标注其字节宽度为 4见 PrimitiveType.javaFLOAT(FLOAT, 4),紧随其后的DOUBLE(DOUBLE, 8)与之形成对照——这正是FLOAT 4 字节、DOUBLE 8 字节这一文档结论在 FE 类型系统中的直接落点。SQL 解析层面FLOAT关键字在词法文件中被定义为独立 token见 StarRocksLex.g4FLOAT: FLOAT;这意味着FLOAT在 DDL 中是大小写不敏感的保留关键字可被语法解析器直接映射为上述PrimitiveType.FLOAT。BE 侧逻辑类型与物理存储在后端BE中FLOAT 对应LogicalType::TYPE_FLOAT 10源码注释明确标注其对应关系为MYSQL_TYPE_FLOAT见 logical_type.hTYPE_FLOAT 10, // MYSQL_TYPE_FLOAT TYPE_DOUBLE 11, // MYSQL_TYPE_DOUBLE类型描述符type descriptor为 FLOAT 分配了4 字节的 slot 大小与 DOUBLE 的 8 字节、BIGINT 的 8 字节区分开见 type_descriptor.cpp 附近的实现case TYPE_INT: case TYPE_FLOAT: case TYPE_DECIMAL32: return 4;在列式存储Column层面FLOAT 列被映射为定长浮点列FixedLengthColumnfloat见 vectorized_fwd.husing FloatColumn FixedLengthColumnfloat;也就是说BE 中每个 FLOAT 数据单元最终对应 C 的float类型32 bit 单精度这从实现上保证了文档所述4 bytes的存储语义。相关类型特征映射还可在 runtime_type_traits.h 中看到ColumnType FloatColumn的关联定义在 type_info.cpp 中可以看到针对TYPE_FLOAT特化的ScalarTypeInfoImpl。一个重要的实现细节FLOAT 不参与数据校验和由于浮点数的二进制表示在不同精度/舍入路径下可能不完全一致BE 在计算数据校验和checksum时显式排除了 FLOAT 与 DOUBLE见 logical_type.h// The approximation of FLOAT/DOUBLE in a certain precision range, the binary of byte is not // a fixed value, so these two types are ignored in calculating checksum. inline bool is_support_checksum_type(LogicalType type) { return type ! TYPE_FLOAT type ! TYPE_DOUBLE ...; }源码注释说明FLOAT/DOUBLE 在特定精度范围内是近似值其二进制字节不是固定值因此被排除在校验和计算之外。这一点对理解副本一致性校验、导入校验等机制的行为很有帮助——包含 FLOAT 列的表的校验和语义与纯整数/定点类型表不同。与其他类型的转换与排序从类型系统看FLOAT 属于浮点类型族float typeBE 通过is_float_type()同时判定 FLOAT 与 DOUBLE见 logical_type.hinline bool is_float_type(LogicalType type) { return type TYPE_FLOAT || type TYPE_DOUBLE; }在类型兼容性判断中两个浮点类型之间、以及浮点类型与整数类型之间均被允许隐式转换见 type_descriptor.cpp。此外FLOAT 与 DOUBLE 都出现在可排序类型列表中sortable_types()见 logical_type.cpp说明它们可用于ORDER BY、比较运算和索引场景。在 DECIMAL.md 的 DECIMAL256 类型转换表中也明确列出了TYPE_DECIMAL256与TYPE_FLOAT、TYPE_DOUBLE之间的双向转换支持说明 FLOAT 可以安全地与高精度定点类型相互 CAST。FLOAT 与其他数值类型的对比与选型将 FLOAT 与 StarRocks 其他数值类型放在一起对比有助于在实际建模中做出正确选择类型字节数有效十进制精度性质典型场景FLOAT4约 7 位近似IEEE 754 单精度传感器数据、评分、粗略统计指标DOUBLE8约 15 位近似IEEE 754 双精度科学计算、更宽范围的浮点指标DECIMAL(P,S)变长32/64/128/256 bit最高 76 位有效数字精确定点金额、汇率、账务等要求精确的场景整数类型TINYINT/SMALLINT/INT/BIGINT/LARGEINT1/2/4/8/16完全精确精确定长整数计数、ID、枚举等选型建议需要精确小数运算金额、计量结算使用 DECIMAL避免 FLOAT 的舍入误差在累加、比较中放大数据量巨大且对精度要求宽松监控指标、统计近似值优先使用 FLOAT存储开销仅为 DOUBLE 的一半列式存储下可显著节省空间并提升扫描吞吐需要更高精度但可接受近似分析型浮点指标使用 DOUBLE其约 15 位有效数字已覆盖绝大多数科学计算需求永远不要用 FLOAT 做主键或等值连接键由于表示误差WHERE float_col 0.1这类条件可能得不到预期结果等值匹配应使用精确类型。使用注意事项总结基于文档与源码使用 FLOAT 时应注意以下几点精度截断而非报错超出约 7 位有效数字的部分会被静默舍入不会返回错误如需感知溢出/精度问题可结合sql_mode的ERROR_IF_OVERFLOW等设置详见 DECIMAL.md 中的用法说明约束行为比较与聚合需谨慎避免对 FLOAT 做精确等值比较做SUM/AVG聚合时误差会累积对精度敏感的统计建议先 CAST 到 DOUBLE 或 DECIMAL校验和语义差异FLOAT/DOUBLE 列不参与 BE 的 checksum 计算见 logical_type.h 的源码注释这与精确类型不同表模型与索引FLOAT 可用于明细表、聚合表的指标列以及排序场景sortable_types()包含 FLOAT但作为键列需考虑近似类型比较的语义问题与 DECIMAL256 互转FLOAT 可与 DECIMAL256 双向转换跨类型计算前建议显式CAST以避免隐式转换带来的意外精度变化。延伸阅读FLOAT 官方文档本文核心依据DOUBLE.md8 字节双精度浮点类型与 FLOAT 对比阅读DECIMAL.md高精度定点类型含 Fast DECIMAL 与 DECIMAL256 的完整说明数值类型总览numeric.mdxFE 类型注册PrimitiveType.javaBE 逻辑类型定义logical_type.hBE 列式存储映射vectorized_fwd.h。【免费下载链接】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),仅供参考