存储大量的总金额和 memory/storage 影响 - BigDecimal 与 Integer 和最佳实践?

Storing a large number of money totals and memory/storage implications - BigDecimal vs Integer and best practices?

BigDecimal class 是 Java 中处理货币单位的标准方式。但是,当存储极大量的数据时(想想每个用户数百万至数十亿个条目),与 int 等原语相比,必须考虑额外的存储空间 space:根据 this 答案单个 BigDecimal 对应于大约 36 + Ceiling(log2(n)/8.0) 字节(不包括一些元数据描述符等),而 int 通常是 4 字节。

当存储数百万个条目时,这当然会导致内存使用量和存储量的显着增加 space(例如,将 MongoDB 与类型的描述符一起使用,或者PostgreSQL numeric 类型似乎至少对应于 8 字节,我不熟悉例如 Cassandra,所以我不确定会有什么存储影响)。

使用 BigDecimal 类型的另一种方法是存储 整数美分 (或者选择最小的面额,即 == 10000 hundredths of a cent,根据精度要求)。这不仅会减少程序的压力,还会减少数据集中除最大值以外的所有值所需的存储空间(无论如何都是异常值,可能需要单独处理)。

这是一个可行的选择吗?在这种情况下是否有任何必须避免的陷阱?这种方法是否符合现行标准(例如外部审计)?

注意:这仅适用于存储数据,数据仍会以适当的格式显示给用户,具体取决于各种因素(即区域设置,例如美国为 $31,383.22)。

  • 在数据库方面 DECIMAL 没有问题(虽然可能在 NOSQL 数据库中)。
  • 在java方面BigDecimal也没有问题,如果你不在内存中保存大量数据的话。另外请注意,int-range 中正常数字的 BigDecimal 与字符串相当。这些都是可以接受的小物件,java可以很好的处理。

Cents是可行的,但也不能完全逃避BigDecimal。在大多数国家/地区,税收等财务计算都需要一定的精度,例如小数点后 6 位。 此外,标准 java 组件不提供 "virtual" 小数点。 从标准 output/input、JSF 到 JasperReports 等等。

应该提到 BigDecimal 的用法也很冗长。

所以我会从 BigDecimal 开始,以快速获得一个工作系统,并且只有在大量 "spreadsheet" 工作时才恢复到美分。