You need to enable JavaScript to run this app. MongoDB C# 驱动为何默认用字符串存储decimal而非BsonType.Decimal128?
优惠活动
大模型
产品
解决方案
定价
更多

MongoDB C# 驱动为何默认用字符串存储decimal而非BsonType.Decimal128?

MongoDB C#驱动默认字符串存储decimal的原因说明

该默认存储行为确实是出于向后兼容的核心考量,相关逻辑和方案说明如下:

历史背景与规则由来

MongoDB 3.2及更早版本没有原生的Decimal128 BSON数据类型,当时C#的decimal类型没有可匹配的原生BSON类型可选:

  • 若使用BSON double类型存储,会出现十进制精度丢失问题,无法满足财务、金融类场景的精度要求
  • 以字符串形式存储可以100%保留decimal的完整数值精度,且所有MongoDB版本都能正常读写,是当时兼容性最优的方案
    因此驱动从最初版本就选择了字符串作为decimal的默认存储格式。

未调整默认规则的原因

在MongoDB 3.2推出原生Decimal128类型后,C#驱动也同步支持了该类型的序列化,但始终没有修改默认存储规则:
如果贸然把默认存储从字符串切换为Decimal128,所有存量老应用升级驱动版本后,会直接出现两类严重兼容问题:

  • 新写入的decimal数据以Decimal128格式存储,和历史的字符串格式数据不统一
  • 读取历史字符串格式的decimal数据时,会触发类型不匹配的反序列化异常,导致业务报错
    出于对存量用户的兼容承诺,驱动不会主动修改这类可能破坏现有系统的默认行为。不少开发者反馈该默认设计不符合直觉,对新应用来说直接使用原生Decimal128存储本应是更合理的默认选择,但该约束下的默认规则至今没有调整,也给不少新上手的开发者造成了困扰。

新应用的推荐配置方案

对于全新项目,全局配置DecimalSerializer使用BsonType.Decimal128作为存储表示是完全合理的,可充分利用原生Decimal128的数值计算、范围查询优势。全局配置的示例代码如下:

// 应用启动初始化MongoDB驱动时执行全局配置
BsonSerializer.RegisterSerializer(
    typeof(decimal),
    new DecimalSerializer(BsonType.Decimal128)
);
BsonSerializer.RegisterSerializer(
    typeof(decimal?),
    new DecimalSerializer(BsonType.Decimal128, allowNull: true)
);

如果项目存在历史的字符串格式decimal数据,还可以进一步配置序列化规则,同时兼容新旧两种格式的读写,无需额外数据迁移。

内容的提问来源于stack exchange,提问作者Konrad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.29 01:06:10