关系型数据库存储78位精度数值(如ETH uint256)的可行方案
加密货币超精度数值数据库存储落地方案
针对SQL Server这类数据库默认数值类型最多仅支持38位精确数字、无法存储uint256类型(最高78位数字)加密货币数值的问题,以下是生产环境验证过的可行方案,既可以完全避免精度损失,也能保留SQL原生数值运算能力:
- 分段数值存储
把全精度的超长数值按固定基数拆成多个标准数值字段存储,比如针对单字段最多存38位数字的数据库,选合适的10的整数次幂作为拆分基数,保证拆分后的每一段数值都不超过单字段的存储上限即可。做SUM等聚合运算时,分别对每个分段字段求和后,在SQL层或应用层处理一次进位逻辑就能得到精确结果;做大小比较时按从高位到低位的顺序逐段判断即可,给分段字段加组合索引后,查询性能和普通数值字段没有差异。 - 选用支持大精度的原生数值类型
如果技术栈允许调整数据库选型,直接使用支持任意精度数值的数据库即可:PostgreSQL的NUMERIC类型没有38位的精度限制,最高可存储上千位的精确十进制数,原生支持所有数值聚合、比较运算,不需要额外改造业务逻辑,迁移成本最低。如果使用MySQL 8.0及以上版本,其DECIMAL类型最高支持65位精度,搭配业务侧的单位裁剪,足够覆盖绝大多数加密货币的存储需求。 - 冷热字段分离存储
日常业务高频用到的数值(比如面向用户展示的代币余额、常规交易统计值),按业务常用单位换算后存为标准DECIMAL类型,满足日常SQL运算需求;全精度的原始链上数值单独存为字符串类型作为冷数据,只在对账、链上数据溯源这类低频场景使用,从业务设计上避开字符串做数值运算的性能问题。
注意:绝对不要用FLOAT、DOUBLE这类二进制浮点数类型存储金额类数值,其天然的精度丢失是不可逆的,哪怕仅差1个最小单位,在转账、对账场景都可能造成实际资损。
内容的提问来源于stack exchange,提问作者greenglas
相关产品推荐
相关产品推荐

