需要在MongoDB中存储高精度小数值

8

我对MongoDB的经验很少。我通常处理大规模SQL Server数据库。

MongoDB仅支持double类型,没有小数。C#驱动程序将小数序列化为字符串。

  • 如果我将小数存储为字符串在MongoDB中,会错过哪些功能?

  • 有没有一种方法可以将小数的默认序列化设置为double(AllowTruncation),而不必在每个属性上放置属性?

  • 如果使用Bson double,我会失去多少精度?

感谢您的帮助!

更新

我有一个现有的应用程序模型,它在C#中使用小数。我想将MongoDB用作新的DB层,并尽可能少地更改现有应用程序。这就是为什么我正在寻找一种将C#中的小数映射到MongoDB中的double的方法。
我知道我会失去精度,并且必须分析其副作用。我唯一剩下的问题是是否有一种方法可以将小数的默认序列化设置为double。

再次感谢。到目前为止,回答和评论都很好。


如果您需要小数精度,请不要使用双精度浮点数。这样做会有改变数据的风险。 - WiredPrairie
可能是MongoDB-值的十进制类型如何处理?的重复问题。 - WiredPrairie
...以及仍然开放的问题:https://jira.mongodb.org/browse/SERVER-1393 - WiredPrairie
谢谢您的回复!非常有用的信息。我仍然需要知道如何在C#中将小数的默认序列化设置为double。 该问题与https://dev59.com/I2gu5IYBdhLWcg3wJT5I不同。 - PeterFromCologne
为什么不直接使用双精度浮点数? - WiredPrairie
2个回答

8
我会部分回答你的问题(因为我不太了解C#)。
那么,如果将小数存储为字符串,你会失去什么呢?
  • 平均而言,您的数字将会更重(每个双精度数字占用8个字节,这意味着每个长度超过8个字符的字符串都会更重)。因此,如果索引建立在此字段上,它们将变得更大。
  • 您将无法使用以数字为参数的运算符$inc, $bit, $mod, $min, $max和2.6版本中的$mul。(也许我忘了某些内容)
  • 您将无法比较数字(也许"1.65"和"1.23"可以作为字符串进行比较,但是带有e和负号的数字肯定不行)。因此,基于比较的操作如$sort和所有这些$gte, $gt, $lte, $lt将无法正常工作。

如果将十进制数存储为双精度浮点数,会失去多少精度

  • 基于 C# 中的 Decimal 具有 28-29 个有效数字,而查看我的第一个链接并检查 双精度规范,您会发现它具有 15-17 个有效数字。这基本上是您将会失去的。
  • 另一个人们在处理双精度浮点数时有时会忘记的非常重要的事情如下所示:

.

db.c.insert({_id : 1, b : 3.44}) 
db.c.update({_id : 1},{$inc : {b : 1}})
db.c.find({b: 4.44})  // WTf, where is my document? There is nothing there

关于第二个子问题:

有没有办法设置小数的默认序列化为double(AllowTruncation),而不必在每个属性上放置属性?

我并不真正理解它,所以我希望有人能够回答它。


8

Mongodb 3.4及2.4版Mongodb C#驱动程序已支持小数类型。

您的文档属性必须具有[BsonRepresentation(BsonType.Decimal128)]属性,该属性位于MongoDB.Bson.Serialization.Attributes命名空间中。

这将映射到MongoDB中的"YourDecimalValue" : NumberDecimal("100.0000")。Robomongo从1.1 Beta版本开始支持新的小数类型。


1
非常感谢回答这个将近4年前的问题! - PeterFromCologne

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接