我很好奇money
数据类型和类似之间是否存在真正的差异decimal(19,4)
(我认为这是内部使用的钱).
我知道这money
是特定于SQL Server的.我想知道是否有令人信服的理由选择一个而不是另一个; 大多数SQL Server示例(例如AdventureWorks数据库)使用money
而不是decimal
价格信息之类的东西.
我应该继续使用money数据类型,还是使用十进制代替?Money输入的字符较少,但这不是有效的原因:)
你永远不应该用钱.它不精确,是纯垃圾; 总是使用十进制/数字.
运行这个看看我的意思:
DECLARE @mon1 MONEY, @mon2 MONEY, @mon3 MONEY, @mon4 MONEY, @num1 DECIMAL(19,4), @num2 DECIMAL(19,4), @num3 DECIMAL(19,4), @num4 DECIMAL(19,4) SELECT @mon1 = 100, @mon2 = 339, @mon3 = 10000, @num1 = 100, @num2 = 339, @num3 = 10000 SET @mon4 = @mon1/@mon2*@mon3 SET @num4 = @num1/@num2*@num3 SELECT @mon4 AS moneyresult, @num4 AS numericresult
产量:2949.0000 2949.8525
对于那些说你不用钱分钱的人:
这是我计算相关性的一个查询,将其更改为货币会产生错误的结果.
select t1.index_id,t2.index_id,(avg(t1.monret*t2.monret) -(avg(t1.monret) * avg(t2.monret))) /((sqrt(avg(square(t1.monret)) - square(avg(t1.monret)))) *(sqrt(avg(square(t2.monret)) - square(avg(t2.monret))))), current_timestamp,@MaxDate from Table1 t1 join Table1 t2 on t1.Date = traDate group by t1.index_id,t2.index_id
SQLMenace表示资金不准确.但是你不要用钱来分钱/分钱!3美元乘50美分多少钱?150美元?你用标量乘以/除以钱,这应该是十进制的.
DECLARE @mon1 MONEY, @mon4 MONEY, @num1 DECIMAL(19,4), @num2 DECIMAL(19,4), @num3 DECIMAL(19,4), @num4 DECIMAL(19,4) SELECT @mon1 = 100, @num1 = 100, @num2 = 339, @num3 = 10000 SET @mon4 = @mon1/@num2*@num3 SET @num4 = @num1/@num2*@num3 SELECT @mon4 AS moneyresult, @num4 AS numericresult
得到正确的结果:
moneyresult numericresult --------------------- --------------------------------------- 2949.8525 2949.8525
money
只要您不需要超过4位十进制数字就可以了,并且确保您的标量 - 不代表金钱 - 是decimal
.
如果你不知道自己在做什么,一切都很危险
即使是高精度的十进制类型也无法节省一天:
declare @num1 numeric(38,22) declare @num2 numeric(38,22) set @num1 = .0000006 set @num2 = 1.0 select @num1 * @num2 * 1000000
1.000000 < - 应该是0.6000000
该money
类型是整数
文本表示smallmoney
和decimal(10,4)
可能看起来相似,但这并不能使它们互换.当你看到日期存储为时,你会畏缩varchar(10)
吗?这是一回事.
在幕后,money
/ smallmoney
只是一个bigint
/ int
文本表示中的小数点money
是视觉绒毛,就像yyyy-mm-dd日期中的破折号一样.SQL实际上并不在内部存储它们.
关于decimal
vs money
,选择适合您需求的任何内容.的money
存在类型,因为储存计费值作为单位的1 /第一万整数倍是很常见的.此外,如果您正在处理除简单加法和减法之外的实际金钱和计算,您不应该在数据库级别执行此操作! 使用支持Banker Rounding(IEEE 754)的库在应用程序级别执行此操作
我意识到WayneM已经声明他知道钱是特定于SQL Server的.但是,他问是否有任何理由使用小数点数或反之亦然,我认为仍然应该说明一个明显的原因并且使用小数意味着如果你不得不改变你的DBMS,那就更少担心了 - 这可能发生.
使您的系统尽可能灵活!
好吧,我喜欢MONEY
!它比一个字节便宜DECIMAL
,并且计算执行得更快,因为(在封面下)加法和减法操作基本上是整数运算.@ SQLMenace的例子 - 对于不知道的人来说是一个很好的警告 - 同样可以应用于INT
egers,结果为零.但是,没有理由不在适当的地方使用整数.
因此,MONEY
当您正在处理的内容是MONEY
根据其遵循的数学规则(与INT
eger 相同)使用时,它非常"安全"且适合使用.
如果SQL Server提升MONEY
s 和DECIMAL
s(或FLOAT
s?)的分割和乘法会更好- 可能,但他们没有选择这样做; 他们也没有选择在分裂时促进INT
艾格斯FLOAT
.
MONEY
没有精确问题; 那DECIMAL
得面对具有计算过程中使用较大的中间类型仅仅是使用该类型的"功能"(我不肯定实际上多远,即"功能"延伸).
回答具体问题,一个"令人信服的理由"?好吧,如果你想在一个或两个SUM(x)
地方绝对最大的表现,那么就会有优势.x
DECIMAL
MONEY
MONEY
另外,不要忘记它是一个较小的堂兄,SMALLMONEY
只需要4个字节,但它最大限度地214,748.3647
用于 - 这对于钱而言非常小 - 所以通常不太合适.
为了证明使用更大的中间类型的观点,如果将中间体明确地分配给变量,则会DECIMAL
遇到同样的问题:
declare @a decimal(19,4) declare @b decimal(19,4) declare @c decimal(19,4) declare @d decimal(19,4) select @a = 100, @b = 339, @c = 10000 set @d = @a/@b set @d = @d*@c select @d
产生2950.0000
(好吧,所以至少是DECIMAL
圆形而不是MONEY
截断 - 与整数相同.)
我们刚刚遇到了一个非常类似的问题,我现在非常喜欢+1,因为除了顶层演示之外从不使用Money.我们有多个表(实际上是销售凭证和销售发票),其中每个表都包含一个或多个货币字段,这是出于历史原因,我们需要按比例计算以计算总发票税与每个税额的相关程度.销售凭证上的行.我们的计算是
vat proportion = total invoice vat x (voucher line value / total invoice value)
这导致现实世界的货币/货币计算导致分割部分的尺度误差,然后乘以不正确的增量比例.当随后添加这些值时,我们最终得到的桶数比例总和不会与总发票金额相加.如果括号中的任何一个值都是小数(我即将投出其中一个),那么增值比例就是正确的.
当括号不存在时,原来这个用来工作,我想因为涉及的值越大,它就能有效地模拟更高的尺度.我们添加了括号,因为它首先进行乘法运算,这在极少数情况下会超出可用于计算的精度,但现在这已经导致了这个更常见的错误.
作为对抗其他答案的一般主旨的对立点.查看货币的许多好处......数据类型!在SQLCAT的关系引擎指南中
具体来说,我会指出以下内容
在客户实施方面,我们发现了一些有关货币数据类型的有趣性能数据.例如,当Analysis Services设置为货币数据类型(来自double)以匹配SQL Server货币数据类型时,处理速度(行/秒)提高了13%.为了在SQL Server Integration Services(SSIS)中获得更快的性能,在30分钟内加载1.18 TB,如SSIS 2008中所述 - 世界记录ETL性能,观察到更改四个小数(9,2)列的大小为在TPC-H LINEITEM表中5个字节到钱(8个字节),批量插入速度提高了20%......性能提升的原因是因为SQL Server的表格数据流(TDS)协议,它具有以紧凑二进制形式传输数据并尽可能接近SQL Server内部存储格式的关键设计原则.根据经验,这在SSIS 2008期间观察到 - 使用Kernrate的世界纪录ETL性能测试; 当数据类型从十进制转换为货币时,协议显着下降.这使得数据传输尽可能高效.复杂数据类型需要额外的解析和CPU周期来处理,而不是固定宽度类型.
所以问题的答案是"它取决于".您需要对某些算术运算更加小心以保持精度,但您可能会发现性能方面的考虑使其值得.
我想对MONEY与NUMERICAL给出不同的看法,主要基于我自己的专业知识和经验...我的观点是MONEY,因为我已经使用了很长时间并且从未真正使用过NUMERICAL ... .
MONEY Pro:
原生数据类型.它使用一个本地数据类型(整数)作为相同的CPU寄存器(32位或64位),所以计算不需要不必要的开销所以它的更小和更快 ... MONEY需要8个字节和数值(19,4 )需要9个字节(大12.5%)......
只要它用于它(因为钱),MONEY就会更快.多快?我SUM
对100万个数据的简单测试表明,MONEY是275毫秒,NUMERIC是517毫秒...这几乎是快两倍 ...为什么SUM测试?见下一个Pro点
最物有所值.MONEY最适合存储资金并进行操作,例如会计.在SUM操作完成后,单个报告可以运行数百万个添加(SUM)和一些乘法.对于非常大的会计应用,它几乎快两倍,而且非常重要......
低精度的钱.现实生活中的金钱不需要非常精确.我的意思是,很多人可能只关心1美分,但是0.01美元怎么样呢?事实上,在我的国家,银行不再关心美分(小数点后的数字); 我不知道美国银行或其他国家......
钱币:
精度有限.MONEY只有四位数(在逗号之后)精度,所以在进行除法之类的操作之前必须进行转换......但是再次money
不需要那么精确并且意味着要用作钱,而不仅仅是数...
但是......大,但这里甚至你的应用程序涉及真钱,但不要在很多SUM操作中使用它,比如会计.如果你使用大量的除法和乘法,那么你不应该使用MONEY ......