应使用 Decimal128 存储金额,因其能精确表示34位十进制数,避免 double 的精度丢失和 int 存分的跨币种缺陷;MongoDB 原生支持,但需用字符串构造、注意驱动版本及聚合中类型混用降级问题。用 Decimal128 存金额,别用 double 或 int金融场景下,double 会丢失精度(比如 19.99 + 0.01 可能算出 19.999999999999996),int 存分又容易在跨币种、小数位不一致(如日元无小数、比特币支持8位)时硬编码出错。MongoDB 原生支持 Decimal128,它按 IEEE 754-2008 实现,能精确表示任意 34 位十进制数,且服务端运算也保持精度。实操建议:插入时必须用 Decimal128 构造器,不能靠 driver 自动转换(例如 Node.js 的 new Decimal128("123.45"),不是 new Decimal128(123.45) ------ 后者仍是浮点字面量)查询聚合时,sum、avg 等累加操作对 Decimal128 字段天然支持,结果仍是 Decimal128;但若混入 int 字段,整个结果会降级为 double注意驱动兼容性:Python PyMongo ≥ 3.4、Node.js MongoDB Driver ≥ 3.0、Java Driver ≥ 3.4 才完整支持 Decimal128 序列化/反序列化流水记录加签名字段 hash 和 prev_hash 防篡改单靠数据库权限控制无法防止管理员或内鬼修改历史流水。需要在应用层写入时生成可验证的链式哈希:每条记录包含自身内容的 SHA-256(不含 _id 和 hash 字段),以及上一条流水的 hash 值。这样任意一条被改,后续所有 prev_hash 校验都会失败。实操建议:计算 hash 时,必须固定字段顺序、统一 JSON 序列化格式(推荐使用严格模式,如 Python 的 json.dumps(..., sort_keys=True, separators=(',', ':'))),否则同样数据生成不同哈希prev_hash 初始值设为空字符串或全零 "0000000000000000000000000000000000000000000000000000000000000000",第一条流水靠此识别不要把私钥存在数据库里;签名用的密钥应由 KMS 或 HSM 托管,应用只调用签名接口校验逻辑不应只查单条,而应从最新一条倒推,直到 prev_hash 为空 ------ 中间任一环断裂即说明被篡改索引设计要覆盖高频查询路径:时间范围 + 账户 + 状态交易流水最常查的是「某账户近7天的成功入账」或「某笔订单关联的所有流水」,单一 _id 索引完全不够。但建太多复合索引又拖慢写入,尤其金融系统写入压力大。 标贝科技 标贝科技-专业AI语音服务的人工智能开放平台
相关推荐
circuitsosk32 分钟前
NL2SQL在工业级场景下的精度优化:Schema Linking + 动态Few-shot实战2401_894915532 小时前
GEO 优化源码全解析:从搜索引擎到 AI 引擎的底层改写逻辑kobe_OKOK_6 小时前
DRF接口幂等操作廿士7 小时前
python脚本使用相关正儿八经的少年7 小时前
布隆过滤器(解决redis缓存穿透步骤之一)青 春 记 忆7 小时前
零基础入门python19:Flask账本第一步——应用工厂、蓝图和健康检查朦胧之7 小时前
Python 后端核心知识xrandzj7 小时前
MySQL8.0 从零通关核心操作手册(Ubuntu实战版)我不会插花弄玉7 小时前
4.数据类型【由浅入深-MySQL】denggun123458 小时前
yield