Decimal(19,4)或者Decimal(19.2) - 我应该使用哪一个?

23

这听起来像是一个愚蠢的问题,但我注意到在许多电子商务相关项目的表格设计中,货币几乎总是使用decimal(19, 4)。

为什么刻度上要用4呢?为什么不是2?

也许我忽略了未来可能出现的计算问题?


当您拥有一个 MS-SQL 数据库时,您可以使用货币数据类型。 - Joachim Sauer
@JoachimSauer - 十进制比货币更精确,因为我看到十进制被用在许多电子商务类型的例子中。 - user1447679
更高的精度有助于减少舍入误差 - 只是一个猜测。 - Dinesh
4
DECIMAL(19, 4) 是一个受欢迎的选择,可以参考这里,也可以查看这里世界货币格式来决定使用多少小数位,希望有所帮助。 - Shaiju T
5个回答

28

首先,其他答案中有一些错误的建议。请注意以下内容(在64位架构的64位操作系统上):

declare @op1 decimal(18,2) = 0.01
       ,@op2 decimal(18,2) = 0.01;

select result = @op1 * @op2;

result
---------.---------.---------.---------
0.0001

(1 row(s) affected)
注意标题下划线的数量-共39个(我每隔十个用句点替代以便计数)。这恰好足够38个数字(最大允许值,并且64位CPU上默认值)加上显示的小数点。虽然两个操作数都声明为decimal(18,2),但计算是使用decimal(38,4)数据类型进行的并报告了结果。(我在64位机器上运行SQL 2012-某些细节可能因机器架构和操作系统而异。)
因此,很明显没有丢失精度,相反,只有可能发生溢出,而不是精度损失。这是所有十进制操作数计算都作为整数算术执行的直接后果。您偶尔会看到这种现象,在这种情况下,中间字段类型的智能感知报告为int而不是decimal
考虑上面的例子。两个操作数都是decimal(18,2)类型,并存储为值为1的整数,小数点后有2位。相乘后,积仍为1,但比例通过添加比例来计算,从而创建具有整数值1和比例4的结果,该结果为值为0.0001且类型为decimal(18,4)的整数,存储为值为1和比例4的整数。
再次阅读最后一段。
再洗涤一遍。
在实践中,在64位机器和操作系统上,实际上将其存储为* decimal(38,4),因为计算是在具有免费额外位的CPU上执行的。
回到您的问题-世界上所有主要货币(据我所知)只需要2个小数位,但还有少数需要4个小数位,并且有金融交易,例如货币交易和债券销售,法律规定必须使用4个小数位。当设计money数据类型时,微软似乎选择了可能需要的最大比例而不是正常比例。鉴于实际上只有少数交易和公司需要超过19位数字的精度,这似乎非常明智。
如果您具备以下条件:
1. 高度预期仅处理主要货币(当前时间仅需要2位比例); 和 2. 不期望进行法律要求需要4位比例的交易
那么您可以安全地使用带有比例2的decimal类型(如decimal(19,2)decimal(18,2)decimal(38,2))代替money。这将简化一些转换,并且在以上假设成立的情况下没有成本。这种情况的典型示例是在跟踪到美分的GL或子帐簿会计系统中。但是,股票或债券交易系统不符合这些假设,因为在这些情况下法律要求使用4位比例。
区分两种情况的方法是交易是否以centspercents报告,这只需要2个小数位,还是以basis points报告,这需要4个小数位。
如果您对适用于您的编程环境的情况有任何疑问,请咨询您的控制器或财务总监,了解您的应用程序的法律和GAAP要求。他/她将能够向您提供明确的建议。

5
非常详细,思考得很周到。谢谢Pieter。 - user1447679

2

类似于汽油价格会使用额外的“刻度”位置。你肯定见过每加仑1.959美元的汽油价格,对吧?


2

在SQL中,19是整数的数量,4是小数的数量。

如果你只有2个小数位,并且存储了一些计算结果,导致超过2个小数位,那么“没有办法”存储这些额外的小数位。

一些货币使用超过2个小数位。

使用数据类型decimal而不是money。


1
19不是整数的总数吗?而4是从该总数中取出,用于小数点右侧的使用? - user1447679
1
是的,19 是整数的数量(包括小数点后)。所以 Decimal(10,3)最多可以有一个数字为 9999999.999 [1234567.123]。 - Øyvind Berg
你能想到一个需要使用4个刻度而不是2个的例子吗?比如说,对于存储每月订阅价格的表格。寻找一个例子场景、可能的计算或一些原因,说明为什么在未来使用4个刻度会有帮助。 - user1447679
1
如果你只是进行加减运算,那么2位数字的精度就足够了。但是在除法(或计算百分比)时,你确实需要超过2位数字的精度。例如,考虑从工资单中计算税款扣除。不要不信任我,看看理查德·普莱尔主演的《超人III》就知道了。 - George Mastros

0

当使用十进制数时,根据您的业务需求,您可以自行决定如何使用。

但是,当您在SQL中使用Money数据类型时,默认情况下会存储4位小数。


0

虽然OP的问题是关于比例尺的,但让我们来探讨一下为什么19是SQL Server上十进制数的流行精度。

根据this文档,这是十进制数使用的存储空间:

精度 存储字节
1 - 9 5
10-19 9
20-28 13
29-38 17

因此,1个精度使用的空间与9相同,而10使用的空间与19相同。

在实际应用中,9对于货币来说可能太少了,特别是如果您选择4的比例尺,那么您将处于-99999.9999和99999.9999之间。

但对于任何可以想象到的情况,19足矣,这也是SQL Server货币数据类型使用它的原因。

如果数据库中存在一些错误数据,可以使用28或38以防止转换时出现错误。


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