Way*_*ina 420 sql-server types
我很好奇money数据类型和类似之间是否存在真正的差异decimal(19,4)(我认为这是内部使用的钱).
我知道这money是特定于SQL Server的.我想知道是否有令人信服的理由选择一个而不是另一个; 大多数SQL Server示例(例如AdventureWorks数据库)使用money而不是decimal价格信息之类的东西.
我应该继续使用money数据类型,还是使用十进制代替?Money输入的字符较少,但这不是有效的原因:)
SQL*_*ace 308
你永远不应该用钱.它不精确,是纯垃圾; 总是使用十进制/数字.
运行这个看看我的意思:
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
Run Code Online (Sandbox Code Playgroud)
产量: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
Run Code Online (Sandbox Code Playgroud)
con*_*tor 264
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
Run Code Online (Sandbox Code Playgroud)
得到正确的结果:
moneyresult numericresult --------------------- --------------------------------------- 2949.8525 2949.8525
money只要您不需要超过4位十进制数字就可以了,并且确保您的标量 - 不代表金钱 - 是decimal.
Ano*_*non 57
如果你不知道自己在做什么,一切都很危险
即使是高精度的十进制类型也无法节省一天:
declare @num1 numeric(38,22)
declare @num2 numeric(38,22)
set @num1 = .0000006
set @num2 = 1.0
select @num1 * @num2 * 1000000
Run Code Online (Sandbox Code Playgroud)
1.000000 < - 应该是0.6000000
该money类型是整数
文本表示smallmoney和decimal(10,4)可能看起来相似,但这并不能使它们互换.当你看到日期存储为时,你会畏缩varchar(10)吗?这是一回事.
在幕后,money/ smallmoney只是一个bigint/ int 文本表示中的小数点money是视觉绒毛,就像yyyy-mm-dd日期中的破折号一样.SQL实际上并不在内部存储它们.
关于decimalvs money,选择适合您需求的任何内容.的money存在类型,因为储存计费值作为单位的1 /第一万整数倍是很常见的.此外,如果您正在处理除简单加法和减法之外的实际金钱和计算,您不应该在数据库级别执行此操作! 使用支持Banker Rounding(IEEE 754)的库在应用程序级别执行此操作
Dea*_*ean 40
我意识到WayneM已经声明他知道钱是特定于SQL Server的.但是,他问是否有任何理由使用小数点数或反之亦然,我认为仍然应该说明一个明显的原因并且使用小数意味着如果你不得不改变你的DBMS,那就更少担心了 - 这可能发生.
使您的系统尽可能灵活!
dsz*_*dsz 30
好吧,我喜欢MONEY!它比一个字节便宜DECIMAL,并且计算执行得更快,因为(在封面下)加法和减法操作基本上是整数运算.@ SQLMenace的例子 - 对于不知道的人来说是一个很好的警告 - 同样可以应用于INTegers,结果为零.但是,没有理由不在适当的地方使用整数.
因此,MONEY当您正在处理的内容是MONEY根据其遵循的数学规则(与INTeger 相同)使用时,它非常"安全"且适合使用.
如果SQL Server提升MONEYs 和DECIMALs(或FLOATs?)的分割和乘法会更好- 可能,但他们没有选择这样做; 他们也没有选择在分裂时促进INT艾格斯FLOAT.
MONEY没有精确问题; 那DECIMAL得面对具有计算过程中使用较大的中间类型仅仅是使用该类型的"功能"(我不肯定实际上多远,即"功能"延伸).
回答具体问题,一个"令人信服的理由"?好吧,如果你想在一个或两个SUM(x)地方绝对最大的表现,那么就会有优势.xDECIMALMONEYMONEY
另外,不要忘记它是一个较小的堂兄,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
Run Code Online (Sandbox Code Playgroud)
产生2950.0000(好吧,所以至少是DECIMAL圆形而不是MONEY截断 - 与整数相同.)
小智 12
我们刚刚遇到了一个非常类似的问题,我现在非常喜欢+1,因为除了顶层演示之外从不使用Money.我们有多个表(实际上是销售凭证和销售发票),其中每个表都包含一个或多个货币字段,这是出于历史原因,我们需要按比例计算以计算总发票税与每个税额的相关程度.销售凭证上的行.我们的计算是
vat proportion = total invoice vat x (voucher line value / total invoice value)
Run Code Online (Sandbox Code Playgroud)
这导致现实世界的货币/货币计算导致分割部分的尺度误差,然后乘以不正确的增量比例.当随后添加这些值时,我们最终得到的桶数比例总和不会与总发票金额相加.如果括号中的任何一个值都是小数(我即将投出其中一个),那么增值比例就是正确的.
当括号不存在时,原来这个用来工作,我想因为涉及的值越大,它就能有效地模拟更高的尺度.我们添加了括号,因为它首先进行乘法运算,这在极少数情况下会超出可用于计算的精度,但现在这已经导致了这个更常见的错误.
Mar*_*ith 12
作为对抗其他答案的一般主旨的对立点.查看货币的许多好处......数据类型!在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操作中使用它,比如会计.如果你使用大量的除法和乘法,那么你不应该使用MONEY ......
以前的所有帖子都提出了有效的观点,但有些没有准确回答问题。
问题是:当我们已经知道它是一种不太精确的数据类型并且如果用于复杂计算会导致错误时,为什么有人更喜欢它?
当您不会进行复杂的计算并且可以用这种精度来换取其他需求时,您就可以使用金钱。
例如,当您不必进行这些计算,并且需要从有效货币文本字符串导入数据时。此自动转换仅适用于 MONEY 数据类型:
SELECT CONVERT(MONEY, '$1,000.68')
Run Code Online (Sandbox Code Playgroud)
我知道您可以制作自己的导入程序。但有时您不想重新创建具有全球特定区域设置格式的导入例程。
另一个例子,当您不必进行这些计算(您只需要存储一个值)并且需要保存 1 个字节时(钱需要 8 个字节,decimal(19,4) 需要 9 个字节)。在某些应用程序(快速 CPU、大 RAM、慢 IO)中,例如读取大量数据,这也可以更快。
我在准确性主题中找到了使用小数而不是金钱的原因。
DECLARE @dOne DECIMAL(19,4),
@dThree DECIMAL(19,4),
@mOne MONEY,
@mThree MONEY,
@fOne FLOAT,
@fThree FLOAT
SELECT @dOne = 1,
@dThree = 3,
@mOne = 1,
@mThree = 3,
@fOne = 1,
@fThree = 3
SELECT (@dOne/@dThree)*@dThree AS DecimalResult,
(@mOne/@mThree)*@mThree AS MoneyResult,
(@fOne/@fThree)*@fThree AS FloatResult
Run Code Online (Sandbox Code Playgroud)
只需测试一下并做出决定。
当您需要对值进行乘法/除法时,您不应该使用金钱。货币的存储方式与整数的存储方式相同,而小数则存储为小数点和小数位。这意味着货币在大多数情况下都会降低准确性,而十进制只有在转换回原始比例时才会出现这种情况。货币是定点的,因此在计算过程中其规模不会改变。然而,由于它在打印为十进制字符串时是固定点(而不是基数为 2 的字符串中的固定位置),因此可以精确表示最大为 4 的值。所以加减法的话,钱就可以了。
小数内部以 10 为基数表示,因此小数点的位置也是基于 10 基数的。这使得它的小数部分准确地代表了它的价值,就像金钱一样。不同之处在于小数的中间值可以保持高达 38 位的精度。
对于浮点数,该值以二进制形式存储,就好像它是整数一样,并且小数点(或二进制,咳咳)点的位置相对于表示该数字的位。由于它是二进制小数点,因此以 10 为基数的数字会在小数点后失去精度。1/5 或 0.2 无法以这种方式精确表示。货币和小数都不受此限制。
将货币转换为十进制,执行计算,然后将结果值存储回货币字段或变量是很容易的。
从我的角度来看,我希望发生在数字上的事情能够自然发生,而不必过多考虑。如果所有计算都将转换为十进制,那么对我来说我只想使用十进制。我会保留钱字段以供显示之用。
从尺寸上看,我没有看到足够的差异来改变我的想法。Money 需要 4 - 8 个字节,而十进制可以是 5、9、13 和 17。9 个字节可以覆盖 8 个字节的 Money 可以覆盖的整个范围。索引方面(比较和搜索应该具有可比性)。
| 归档时间: |
|
| 查看次数: |
332817 次 |
| 最近记录: |