Decimal(19,4)或Decimal(19.2) - 我应该使用哪个?
在SQL中,19代表整数的位数,4代表小数的位数。
如果你只有2位小数并且存储了一些计算结果,结果超过了2位小数,那么"没有办法"存储这些额外的小数位。
一些货币使用超过2位小数。
使用数据类型decimal,而不是money。
19不是整数的总位数吗?4是从这个总数中减去的,用于小数点右侧的使用?
是的,19是整数的位数(包括小数位)。因此,Decimal(10,3)最大可以有一个数字9999999.999 [1234567.123]。
你能想到使用4位小数而不是2位小数的例子吗?比如说,用于存储每月订阅价格的表。寻找一个例子场景,可能的计算,或者一些原因,4位小数位在未来会有帮助。
如果只进行加减运算,那么2位小数的精度就足够了。但是在进行除法运算(或计算百分比)时,确实需要超过2位小数的精度。例如,考虑从工资单中计算税务扣除的情况。不要不信我,看看里查德·普莱尔主演的《超人3》。
在处理类似于汽油价格的情况时,我们需要使用额外的“scale”位数。你是否见过每加仑1.959美元的汽油价格?
这里提到的问题是关于使用Decimal类型时应该选择Decimal(19,4)还是Decimal(19.2)。Decimal是一种精确的十进制数类型,它可以用来处理需要保留小数位的计算。在这种情况下,我们需要考虑到汽油价格可能出现的小数位数。
首先,我们需要了解Decimal(19,4)和Decimal(19.2)的含义。Decimal(19,4)表示一个19位的数字,其中有4位是小数位。Decimal(19.2)表示一个19位的数字,其中有2位是小数位。
为了解决这个问题,我们需要考虑到汽油价格可能出现的小数位数。如果我们知道汽油价格最多只会有4位小数,那么我们可以选择Decimal(19,4)。这样可以确保我们有足够的位数来表示价格。
然而,如果我们知道汽油价格最多只会有2位小数,那么我们可以选择Decimal(19.2)。这样可以节省存储空间,并保持足够的精度来表示价格。
总结起来,选择Decimal(19,4)还是Decimal(19.2)取决于具体需求。如果我们需要处理可能出现的最大小数位数,那么选择Decimal(19,4)。如果我们知道小数位数有限,并且想要节省存储空间,可以选择Decimal(19.2)。
在实际应用中,我们可以根据具体情况选择合适的Decimal类型,以满足需求并保持适当的精度。这样可以确保我们在处理类似于汽油价格的情况时能够准确地表示和计算。
首先,其他答案中给出的一些建议是不正确的。观察一下(64位操作系统上的64位架构):
declare decimal(18,2) = 0.01 , decimal(18,2) = 0.01; select result = * ; result ---------.---------.---------.--------- 0.0001 (1 row(s) affected)
请注意标题下划线的数量-一共有39个下划线(我将每十个更改为句点以便计数)。这恰好足够38位数字(64位CPU上的最大允许值,并且是默认值)加上显示的小数点。尽管两个操作数都声明为decimal(18,2),但计算是以decimal(38,4)数据类型执行和报告的。(我在64位机器上运行SQL 2012 - 根据机器架构和操作系统,某些细节可能会有所不同。)
因此,明显没有丢失精度。相反,只能发生溢出,而不是精度丢失。这是所有十进制操作数的计算都作为整数算术进行的直接结果。在智能感知中,有时会看到这个现象,当将decimal类型的中间字段的类型报告为int时。
考虑上面的例子。两个操作数都是decimal(18,2)类型,并存储为值为1的整数,缩放为2。相乘后,乘积仍为1,但是通过添加缩放来计算缩放,创建整数值为1和缩放为4的结果,这是一个值为0.0001且类型为decimal(18,4)的整数,存储为值为1和缩放为4的整数。
再读一遍最后一段。
再次重复。
在实践中,在64位机器和操作系统上,这实际上被存储和维持为*decimal(38,4)类型,因为计算是在具有额外位数的CPU上进行的。
回到您的问题-世界上的所有主要货币(据我所知)只需要2位小数,但还有少数几个货币需要4位小数,并且有些金融交易(如货币交易和债券销售)法律要求使用4位小数。在设计money数据类型时,Microsoft似乎选择了可能需要的最大缩放,而不是通常所需的缩放。考虑到实际上只有很少的交易和公司需要超过19位精度,这似乎是非常明智的。
如果您:
1. 对只处理主要货币(当前只需要2位缩放)有很高的期望;并且
2. 不期望处理法律要求使用4位缩放的交易
那么您可以安全地使用缩放为2的decimal类型(例如decimal(19,2)或decimal(18,2)或decimal(38,2))而不是money类型。这将简化一些转换,并且在上述假设下不会有额外的成本。这些假设满足的典型情况是在GL或分户账务系统中跟踪交易到分的情况。然而,股票或债券交易系统则不满足这些假设,因为这些情况下法律要求使用4位缩放。
区分这两种情况的方法是交易是否报告为cents或percents(只需要2位缩放),或者报告为basis points(需要4位缩放)。
如果您对适用于您的编程情况不确定,请咨询您的财务总监或财务主管,了解您的应用程序的法律和GAAP要求。(他/她将能够给您明确的建议。)
非常详细和深思熟虑。谢谢Pieter。