正如这里所描述的,金钱类型似乎是不鼓励的。
我的应用程序需要存储货币,我应该使用哪种数据类型?数字、金钱还是浮动?
正如这里所描述的,金钱类型似乎是不鼓励的。
我的应用程序需要存储货币,我应该使用哪种数据类型?数字、金钱还是浮动?
当前回答
使用BigInt将货币存储为正整数,表示以最小货币单位表示的货币价值(例如,100美分存储$1.00,100存储¥100(日元,一种零十进制货币)。这正是Stripe所做的——它是全球电子商务领域最重要的金融服务公司之一。
来源:参见https://stripe.com/docs/currencies上的“零十进制货币”
其他回答
我保持所有的货币字段为:
数字(15,6)
使用这么多小数点数位似乎有些过分,但如果你需要处理多种货币,你就需要如此精确的转换。无论我呈现给用户什么,我总是存储到美元。这样,我就可以很容易地转换到任何其他货币,给定当天的汇率。
如果你只做一种货币,最糟糕的是你浪费了一些空间来存储一些0。
使用存储为bigint的64位整数
存储在小货币单位(美分)中,如果美分不够细,则使用大乘数来创建更大的整数。我建议你用100万美元除以100万美元。
例如:$ 5123.56可以存储为5123560000微美元。
使用简单,与每种语言兼容。 精确到可以处理一分钱的分数。 适用于非常小的单位定价(如广告印象或API费用)。 用于存储的数据大小小于字符串或数字。 易于通过计算和在最终输出时应用舍入来保持精度。
数值与强制2单位精度。永远不要使用float或float之类的数据类型来表示货币,因为如果你这样做,当财务报告的底线数字不正确时,人们会不高兴的。
据我所知,货币类型只是由于历史原因而被保留了下来。
举个例子:1伊朗里亚尔等于0.000030美元。如果您使用的小数位数少于5位,那么1个IRR将在转换后四舍五入为0美元。我知道我们在这里是均分的,但我认为在处理金钱问题时,越安全越好。
你的选择是:
Bigint:以分为单位存储金额。这就是EFTPOS事务所使用的。 Decimal(12,2):精确地存储小数点后两位的金额。这是大多数通用账本软件使用的。 浮动:糟糕的想法-不够准确。这是天真的开发人员使用的方法。
选项2是最常见和最容易使用的。将精度(在我的示例中为12,意味着总共有12个数字)设置为最适合您的大小。
请注意,如果您正在将计算结果(例如涉及汇率)的多个事务聚合到具有业务意义的单个值中,则精度应该更高,以提供准确的宏值;考虑使用decimal(18,8)之类的值,这样和是准确的,各个值可以四舍五入到精确的分值以便显示。
你的消息来源绝不是官方的。这本书写于2011年,我甚至不认识作者。如果货币类型被官方“劝阻”,PostgreSQL会在手册中这样说——但它并没有。
要获得更多的官方来源,请阅读pgsql-general中的这篇文章(就在本周!),其中包括D’arcy J.M. Cain (money类型的原始作者)和Tom Lane等核心开发人员的声明:
关于最近版本改进的相关回答(和评论!):
Jasper Report:无法获取类“org.postgresql.util.PGmoney”的字段“x”的值
基本上,钱有它的(非常有限的)用途。Postgres Wiki建议在很大程度上避免它,除了那些狭义定义的情况。与数字相比,它的优势在于性能。
十进制只是Postgres中数字的别名,广泛用于货币数据,是一种“任意精度”类型。手册:
numeric类型可以存储数字数量非常大的数字。 特别推荐用于存储货币金额和其他 需要精确的数量。
就我个人而言,我喜欢将货币存储为表示美分的整数(如果分数美分从未出现的话)。这比上面提到的任何其他方法都更有效。