哪种SQL Server字段类型最适合存储价格值?

时间:2010-06-03 03:20:21

标签: c# sql-server linq-to-sql database-design query-optimization

我想知道SQL Server中价格字段对于类似商店的结构的最佳类型是什么?

查看this overview我们有数据类型称为 money smallmoney ,然后我们有十进制/数字,最后浮动真实

名称,内存/磁盘使用情况和值范围:

  • 资金: 8个字节(值:-922,337,203,685,477.5808至+922,337,203,685,477.5807)
  • Smallmoney: 4个字节(值:-214,748.3648到+214,748.3647)
  • 十进制: 9 [默认,分钟。 5]字节(值:-10 ^ 38 +1到10 ^ 38 -1)
  • Float: 8个字节(值:-1.79E + 308到1.79E + 308)
  • 真实: 4个字节(值:-3.40E + 38到3.40E + 38)

将价格值存储在这些类型中真的很明智吗?那怎么样。 INT?

  • Int: 4个字节(值:-2,147,483,648到2,147,483,647)

让我们说一家商店使用美元,他们有美分,但我认为价格不是49.2142342,因此使用大量小数显示美分似乎浪费了SQL带宽。其次,大多数商店不会显示200.000.000附近的任何价格(至少在正常的网店中,除非有人试图向我出售巴黎着名的塔楼)

那么为什么不去找一个int?

一个int很快,只有4个字节,你可以通过以美分而不是美元保存值来轻松地生成小数,然后在显示值时除以。

另一种方法是使用4个字节的smallmoney,但是这需要CPU的数学部分来进行计算,其中Int是整数幂......在缺点上你需要划分每个单一结果。

使用smallmoney / money字段时,区域设置是否存在“货币”相关问题?在C#/ .NET中这些转移的内容是什么?

任何利弊?去整数价格还是小钱币或其他?

您的经验告诉我什么?

7 个答案:

答案 0 :(得分:21)

如果您完全确定您的数字将始终保持在smallmoney的范围内,请使用它,您可以节省几个字节。否则,我会使用money。但请记住,这些天存储很便宜。 1亿条记录上的额外4个字节仍然不到半个GB。正如@marc_s指出的那样,如果可以减少SQL服务器的内存占用,则使用smallmoney

长话短说,如果你可以逃脱smallmoney,那么。如果您认为可能超过最大值,请使用money

但是,使用浮动十进制类型,否则你会得到四舍五入的问题并开始失败或获得随机分数,除非你正确处理它们。

我反对使用int的论点:为什么要通过存储int重新发明轮子然后必须记住除以100(10000)来检索值并在你去存储时再乘以值。我的理解是货币类型无论如何都使用intlong作为底层存储类型。

就.NET中相应的数据类型而言,它将是decimal(这也将避免C#代码中的舍入问题)。

答案 1 :(得分:9)

如果您要存钱,请使用Money数据类型(除非像国债那样建模大量资金) - 它避免了精确/舍入问题。

The Many Benefits of Money…Data Type!

答案 2 :(得分:7)

USE NUMERIC / DECIMAL。避免使用MONEY / SMALLMONEY。 Here's an example of why。由于舍入错误,MONEY / SMALLMONEY类型迟早会让您失望。货币类型是完全多余的,没有任何用处 - 货币金额只是另一个十进制数字。

最后,MONEY / SMALLMONEY类型是Microsoft专有的。 NUMERIC / DECIMAL是SQL标准的一部分。它们被更多人使用,识别和理解,并得到大多数DBMS和其他软件的支持。

答案 3 :(得分:4)

就个人而言,我会用小钱或钱来存储商店价格。

使用int会增加其他地方的复杂性。

2亿也是韩元或印度尼西亚卢比的完全有效价格......

答案 4 :(得分:3)

SQL数据类型moneysmallmoney都解析为c#decimal类型:

http://msdn.microsoft.com/en-us/library/system.data.sqltypes.sqlmoney(v=VS.71).aspx

所以我想你也可以选择decimal。就个人而言,我一直在使用double一生都在金融行业工作,并且没有遇到性能问题等。实际上,我发现对于某些计算等,拥有更大的数据类型允许更高的准确度。

答案 5 :(得分:1)

我会选择Money数据类型。您可能不会超过Smallmoney中的值,但多个项目很容易超过它。

答案 6 :(得分:0)

在我的当铺应用程序中,典当行运营商从5.00美元贷款到$ 10,000.00 当他们计算贷款金额时,他们将其四舍五入到最接近的美元 避免处理美分(同样适用于利息支付)。当贷款金额高于50.00美元时,它们会将其四舍五入到最接近的5.00美元(即50美元,55美元,60美元......),以便最大限度地减少美元账单的用完。因此,我使用DECIMAL(7,2)作为transaction.calculated_loan_amount,使用DECIMAL(5,0)作为transaction.loan_amount。 该应用程序计算一分钱的贷款金额,并将该金额放在loan_amount中,当它低于50美元时,它将四舍五入到最接近的美元,或者当更高时,它将最接近的$ 5.00。