使用Java的PostgreSQL上的Money数据

Ary*_*rya 13 java sql postgresql currency jdbc

我正在编写一个挖掘货币兑换数据的Java程序.数据可以有多个十进制数字,例如"0.973047".经过一些研究,我发现BigDecimal是Java的正确数据类型,但我应该为PostgreSQL使用哪种数据类型?

Bas*_*que 26

NUMERIC/DECIMAL

正如Joachim Isaksson所说,你想使用NUMERIC/DECIMAL type,作为任意精度类型.

关于NUMERIC/的两个要点DECIMAL:

  • 仔细阅读文档,了解您应该指定比例以避免默认比例为0,这意味着小数部分被删除的整数值.虽然这是Postgres偏离标准SQL的地方之一(给你任何扩展到实现限制).因此,未能指定比例是一个糟糕的选择.
  • 在SQL类型NUMERICDECIMAL接近,但不完全相同根据SQL标准.在SQL:92中,您NUMERIC遵守指定的精度,而DECIMAL允许数据库服务器添加超出您指定的精度.这里再次迷路的Postgres从标准一点,既NUMERICDECIMAL 记录等同.

条款:

  • 精度是数字中的总位数.
  • 比例是小数点右边的位数(小数部分).
  • (精度 - 比例)=小数点左边的位数(整数部分).

清楚你的项目的精度和规模的规格:


  • 精度必须足够大才能处理将来可能需要的更大数量.意思是......今天您的应用程序可能会以数千美元的价格运行,但未来必须执行最终数以百万计的汇总报告.

  • 对于某些会计目的,您可能需要存储最小货币金额的一小部分.含义...超过3或4个小数位,而不是美元一分钱所需的2位数.

避免MONEY类型

Postgres也提供一种MONEY类型.这可能听起来不错,但对大多数用途来说可能不是最好的.一个缺点是,与MONEY刻度由数据库范围内的配置设置中设置基于语言环境.因此,当您切换服务器或进行其他更改时,设置可能会非常危险.此外,您无法控制特定列的设置,而您可以在每个NUMERIC类型列上设置比例.最后,MONEY不是标准SQL,如此标准SQL数据类型列表中所示.Postgres包括MONEY为方便人们从其他数据库系统移植数据.

移动小数点

某些人采用的另一种方法是移动小数点,然后只存储大整数数据类型.

例如,如果将美元存入便士,将任意给定的小数乘以100,则转换为整数类型,然后继续.例如,$ 123.45成为整数12,345.

这种方法的好处是更快的执行时间.操作如sum对整数执行时都非常快.整数的另一个好处是减少了内存使用量.

我发现这种方法很烦人,令人困惑,而且有风险.烦人,因为计算机应该我们工作,而不是反对我们.风险是因为某些程序员或用户可能忽略乘法/除法以转换回小数,从而得出不正确的结果.如果在没有良好支持准确小数的系统中工作,这种方法可能是一种可接受的解决方法.

当我们在SQL和Java中使用DECIMAL/ 时,我认为移动小数点没有任何优势.NUMERICBigDecimal

舍入& NaN

在你的应用程序的编程中,以及在Postgres服务器端进行的任何计算,都要非常小心并注意小数部分的舍入和截断.并测试无意中的NaN弹出.

在app和Postgres这两方面,总是避免浮点数据类型的钱工作.浮点设计用于提高性能,但代价是精确度.计算可能会导致小数部分看似疯狂的额外数字.对于财务/金钱或准确性很重要的其他目的不利.

BigDecimal

是的,在Java中,您需要BigDecimal作为任意精度类型.BigDecimal速度较慢,使用的内存较多,但会准确存储您的金额.SQL NUMERIC/ DECIMAL应映射到此处StackOverflow中BigDecimal讨论的内容.

BigDecimal是Java最好的东西之一.我不知道任何其他类似课程的平台,特别是那些经过精心实施和精心打造的平台,多年来取得了重大改进和修复.

使用BigDecimal绝对比使用较慢的Java的浮点类型,floatdouble.但在现实世界的应用程序中,我怀疑你的资金计算会成为任何瓶颈.此外,您或您的客户想要哪些:最快的金钱计算,还是准确的金钱计算?

我一直认为它是BigDecimalJava中最大的睡眠功能,在许多其他平台上使用Java平台的最重要优势是缺乏对小数的这种复杂支持.

类似的问题:货币的最佳数据类型

  • @KennyEvitt是的,这是浮点的重点(看看我在那里做了什么?)......速度.浮点交易精度以获得更快的性能.现代计算机每秒进行几十亿次计算,你应该在通过黑客数据类型过早优化之前三思而后行.在您的数据类型中使用适当的拟合,直到您确定(可测量地,凭经验)您遇到问题为止. (3认同)

Joa*_*son 5

为了获得尽可能好的(和精确的)精度,您可以使用NUMERIC(或其别名DECIMAL),它具有高精度并允许您决定所需的精度;

数字

用户指定精度,精确到小数点前131072位;小数点后最多 16383 位