正如这里所描述的,金钱类型似乎是不鼓励的。
我的应用程序需要存储货币,我应该使用哪种数据类型?数字、金钱还是浮动?
正如这里所描述的,金钱类型似乎是不鼓励的。
我的应用程序需要存储货币,我应该使用哪种数据类型?数字、金钱还是浮动?
当前回答
使用存储为bigint的64位整数
存储在小货币单位(美分)中,如果美分不够细,则使用大乘数来创建更大的整数。我建议你用100万美元除以100万美元。
例如:$ 5123.56可以存储为5123560000微美元。
使用简单,与每种语言兼容。 精确到可以处理一分钱的分数。 适用于非常小的单位定价(如广告印象或API费用)。 用于存储的数据大小小于字符串或数字。 易于通过计算和在最终输出时应用舍入来保持精度。
其他回答
这不是一个直接的答案,而是一个例子,说明为什么浮动不是货币的最佳数据类型。
由于浮点数在内部的表示方式,它更容易出现舍入错误。
在我们自己的十进制系统中,除2和5之外的任何数都会有四舍五入误差,这两个数都是10的因数。在二进制中,它只有2而不是5,所以即使是“干净的”小数,比如0.2(1/5)也有风险。
如果你尝试以下方法,你就会看到这个结果:
select
0.1::float + 0.2::float as floats, -- 0.30000000000000004
0.1::numeric + 0.2::numeric as numerics --- 0.3
;
这就是那种让审计师抓狂的事情。
数值与强制2单位精度。永远不要使用float或float之类的数据类型来表示货币,因为如果你这样做,当财务报告的底线数字不正确时,人们会不高兴的。
据我所知,货币类型只是由于历史原因而被保留了下来。
举个例子:1伊朗里亚尔等于0.000030美元。如果您使用的小数位数少于5位,那么1个IRR将在转换后四舍五入为0美元。我知道我们在这里是均分的,但我认为在处理金钱问题时,越安全越好。
你的选择是:
Bigint:以分为单位存储金额。这就是EFTPOS事务所使用的。 Decimal(12,2):精确地存储小数点后两位的金额。这是大多数通用账本软件使用的。 浮动:糟糕的想法-不够准确。这是天真的开发人员使用的方法。
选项2是最常见和最容易使用的。将精度(在我的示例中为12,意味着总共有12个数字)设置为最适合您的大小。
请注意,如果您正在将计算结果(例如涉及汇率)的多个事务聚合到具有业务意义的单个值中,则精度应该更高,以提供准确的宏值;考虑使用decimal(18,8)之类的值,这样和是准确的,各个值可以四舍五入到精确的分值以便显示。
我保持所有的货币字段为:
数字(15,6)
使用这么多小数点数位似乎有些过分,但如果你需要处理多种货币,你就需要如此精确的转换。无论我呈现给用户什么,我总是存储到美元。这样,我就可以很容易地转换到任何其他货币,给定当天的汇率。
如果你只做一种货币,最糟糕的是你浪费了一些空间来存储一些0。
使用存储为bigint的64位整数
存储在小货币单位(美分)中,如果美分不够细,则使用大乘数来创建更大的整数。我建议你用100万美元除以100万美元。
例如:$ 5123.56可以存储为5123560000微美元。
使用简单,与每种语言兼容。 精确到可以处理一分钱的分数。 适用于非常小的单位定价(如广告印象或API费用)。 用于存储的数据大小小于字符串或数字。 易于通过计算和在最终输出时应用舍入来保持精度。