【问题标题】:Difference between numeric, float and decimal in SQL ServerSQL Server 中数字、浮点数和小数之间的区别
【发布时间】:2010-11-06 13:54:15
【问题描述】:

numericfloatdecimal 数据类型之间有什么区别,应该在哪些情况下使用?

对于任何一种金融交易(例如薪金领域),首选哪一种?为什么?

【问题讨论】:

  • 上面的十进制和数字链接需要更新为docs.microsoft.com/en-us/sql/t-sql/data-types/…。上面的链接已经不存在了。
  • 通常,在处理金融主题时,使用 Integer 类型很有趣,除了 Floating-point 类型,并将值存储为 cents,而不是 dollars

标签: sql sql-server types


【解决方案1】:

十进制具有固定精度,而浮点具有可变精度。

编辑(未能阅读整个问题): Float(53)(又名 real)是 SQL Server 中的双精度(64 位)浮点数。常规浮点数是单精度(32 位)浮点数。对于大量计算,Double 是精度和简单性的良好组合。您可以使用十进制创建一个非常高精度的数字(最高 136 位),但您还必须小心定义您的精度并正确缩放,以便它可以包含所有必要位数的中间计算。

【讨论】:

【解决方案2】:

不是一个完整的答案,而是一个有用的链接:

“我经常针对十进制值进行计算。在某些情况下,在任何计算之前尽快将十进制值转换为浮点数,从而产生更好的准确性。”

http://sqlblog.com/blogs/alexander_kuznetsov/archive/2008/12/20/for-better-precision-cast-decimals-before-calculations.aspx

【讨论】:

  • 这没有意义。所有其他带有来源的答案都说数字或十进制数据类型是准确的,而浮点数或实数类型是非常接近的近似值。由于精度较低,我可以理解强制转换为浮点数可能允许更快的计算,但不能提高精度。
  • 所有数值数据类型都可能出现上溢和下溢。溢出是一个显式错误,但是,下溢是无声的。 decimalfloat 的下溢特性不同。十进制通过增加精度或比例来尽可能地防止下溢。但是,一旦达到十进制有效数字的限制,下溢就会消失(并且精度会丢失)。浮点数可能具有更广泛的规模范围,而规模限制实际上是下溢的原因。因此,浮动可以具有更好的规模。尽管如此,它仍然是一个不精确类型。
【解决方案3】:

使用 floatreal 数据类型仅当 decimal 提供的精度(最多 38 位) 不足

  • 近似数值数据类型(参见表 3.3)不存储为许多数字指定的精确值;它们存储非常接近的近似值。 (Technet)

  • 避免在 WHERE 子句搜索条件中使用浮点数或实数列,尤其是 = 和 运算符。最好将浮点数和实数列限制为 > 或 Technet)

所以通常选择 Decimal 作为您的数据类型是最好的选择

  • 您的号码可以放入其中。 十进制精度是10E38[~38位]
  • Float 较小的存储空间(可能还有计算速度)对您来说并不重要
  • 需要精确的数字行为,例如在金融应用程序、涉及舍入的操作或相等检查中。 (Technet)

  1. 精确 数值数据类型decimal and numeric - MSDN
  • 数字 = 十进制(5 到 17 个字节)
    • 将映射到 .NET 中的小数
    • 在 SQL Server 中都将 (18, 0) 作为默认(精度、比例)参数
    • scale = 小数点右侧可存储的最大小数位数。
    • money(8 byte) 和 smallmoney(4 byte) 也是精确数据类型,在 .NET 中将映射到 Decimal 并有 4 个小数点 (MSDN)
  1. 近似 数值数据类型float and real - MSDN
  • 实数(4 字节)
    • 将映射到 .NET 中的 Single
    • real 的 ISO 同义词是 float(24)
  • 浮点数(8 字节)
    • 将映射到 .NET 中的 Double

主要来源MCTS Self-Paced Training Kit (Exam 70-433): Microsoft® SQL Server® 2008 Database Development - 第 3 章 - 表、数据类型和声明性数据完整性第 1 课 - 选择数据类型(指南) - 第 93 页

【讨论】:

  • use the float or real data types only if the precision provided by decimal is insufficient - 我认为实数不如小数准确,那么如果小数不足,你怎么写使用实数?
  • real 不太准确,因此不建议使用,除非需要存储比小数(> 10e38)更大的大数字或空间考虑。我猜报价中的精度是指可能的值和幅度而不是精度
  • @BornToCode 这里的“精度”是指您要存储的值的范围。如果您需要存储 1e10 和 1e-10 之间的值,那么 decimal 就可以了。那是 20 的精度。如果您需要存储 1e20 和 1e-20 之间的值,那么,decimal 不能 这样做。那是 40 位的精度。您永远不能将 1e20 和 1e-20 存储在同一个 decimal 字段中。相反,您可以使用float,它在内部将所有内容存储为以 2 为底的日志。这样可以在一个字段中实现全范围的精度,但缺点是只有前 8 位数字是准确的。
  • 我在 BornToCode 和 Iman 的 cmets 中排名第三。我刚刚进行了实验(使用 SQL Server 2012),并且最高精度浮点类型 float(53) 的机器 epsilon 似乎是 2.22044604925031E-16。所以你会从中得到大约 15 个有效数字。另一方面,我可以得到 38 位有效数字。
  • “使用float...” - 谁说的?这是引用还是您的意见?
【解决方案4】:

来自 MSDN 的指南:Using decimal, float, and real Data

数字和十进制数据类型的默认最大精度为 38。 在 Transact-SQL 中,数字在功能上等同于小数 数据类型。 使用小数数据类型存储带小数的数字 当数据值必须完全按照指定存储时。

float 和 real 的行为遵循 关于近似数值数据类型的 IEEE 754 规范。由于浮点数和实数数据类型的近似性质,请不要在精确时使用这些数据类型 数字行为是必需的,例如在金融应用程序中,在 涉及舍入或相等检查的操作。相反,使用 integer、decimal、money 或 smallmoney 数据类型。避免使用浮动 或 WHERE 子句搜索条件中的实列,尤其是 = 和 运算符。 最好将浮点数和实数列限制为 > 或

【讨论】:

  • Scale 列中指定(固定)小数位数。
  • 如果您想要“完全按照指定”,那么从标准的角度来看,numeric 有一些优势,因为它永远不会以比您要求的更精确的方式存储:请参阅stackoverflow.com/a/759606/626804
【解决方案5】:

它们的数据类型优先级不同

十进制数字功能上是相同的,但仍然有数据类型优先级,这很重要在某些情况下。

SELECT SQL_VARIANT_PROPERTY(CAST(1 AS NUMERIC) + CAST(1 AS DECIMAL),'basetype')

生成的数据类型是数字,因为它采用数据类型优先级

按优先级列出的数据类型的详尽列表:

Reference link

【讨论】:

  • 规格明明已经更新了,现在链接页面根本没有提到numeric
【解决方案6】:

浮点数是近似数数据类型,这意味着并非数据类型范围内的所有值都可以精确表示。

Decimal/Numeric 是 Fixed-Precision 数据类型,这意味着该数据类型范围内的所有值都可以用精度和小数位数精确表示。您可以使用小数来省钱。

从十进制或数字转换为浮点数可能会导致一些精度损失。对于 Decimal 或 Numeric 数据类型,SQL Server 将精度和小数位数的每个特定组合视为不同的数据类型。 DECIMAL(2,2) 和 DECIMAL(2,4) 是不同的数据类型。这意味着 11.22 和 11.2222 是不同的类型,但浮点数并非如此。对于 FLOAT(6),11.22 和 11.2222 是相同的数据类型。

您还可以使用 money 数据类型来省钱。这是具有 4 位精度的本机数据类型。大多数专家更喜欢这种数据类型以节省资金。

参考 1 2 3

【讨论】:

    【解决方案7】:

    十进制的情况

    它的基本需求是什么?

    它源于这样一个事实,即计算机最终在内部以二进制格式表示数字。这不可避免地会导致舍入错误。

    考虑一下:

    0.1 (decimal, or "base 10") = .00011001100110011... (binary, or "base 2")
    

    上面的省略号 [...] 表示“无限”。仔细看,有一个无限重复的模式(='0011')

    因此,在某些时候,计算机必须对该值进行四舍五入。这会导致由于重复使用存储不准确的数字而导致的累积错误。

    假设您要存储财务金额(可能有小数部分的数字)。首先,您显然不能使用整数(整数没有小数部分)。 从纯数学的角度来看,自然趋势是使用float。但是,在计算机中,浮点数的数字部分位于小数点之后 - “尾数” - 是有限的。这会导致舍入错误。

    为了克服这个问题,计算机提供了特定的数据类型来限制计算机中十进制数的二进制舍入误差。这些是数据类型 绝对应该用来表示财务金额。这些数据类型的名称通常为 Decimal。例如,在 C# 中就是这种情况。或者,DECIMAL 在大多数数据库中。

    【讨论】:

      【解决方案8】:

      虽然该问题不包括 MONEY 数据类型,但遇到此线程的一些人可能会尝试使用 MONEY 数据类型进行财务计算。

      注意 MONEY 数据类型,它的精度有限。

      在这个 Stackoverflow 问题的答案中有很多关于它的好信息:

      Should you choose the MONEY or DECIMAL(x,y) datatypes in SQL Server?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-07-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-20
        • 2016-04-17
        • 1970-01-01
        相关资源
        最近更新 更多