52

NUMERICSQL 数据类型和之间有什么区别DECIMAL?如果数据库以不同的方式处理这些,我想至少知道如何:

  • SQL 服务器
  • 甲骨文
  • 分贝/2
  • MySQL
  • PostgreSQL

此外,数据库驱动程序如何解释这些类型有什么不同吗?

4

4 回答 4

43

对于几乎所有目的,它们都是相同的。

曾经,不同的供应商对几乎相同的事物使用不同的名称 ( NUMERIC/ DECIMAL)。SQL-92 使它们相同,但有一个细微差别,可能是供应商特定的:

NUMERIC必须与定义的一样精确——因此,如果您在小数点左侧定义 4 个小数位,在其右侧定义 4 个小数位,则 DB 必须始终存储 4 + 4 个小数位,不多也不少.

DECIMAL如果这更容易实现,则可以自由允许更高的数字。这意味着数据库实际上可以存储比指定更多的数字(由于幕后存储有空间用于额外的数字)。这意味着数据库可能允许12345.0000在上面的示例中存储 4 + 4 位小数,但1.00005如果这样做可能会影响任何未来的计算,则仍然不允许存储。

大多数当前的数据库系统将DECIMALandNUMERIC视为完美的同义词,或者视为具有完全相同行为的两种不同类型。如果类型被认为是完全不同的,您可能无法在DECIMAL引用列的NUMERIC列上定义外键约束,反之亦然。

于 2009-12-03T18:48:20.693 回答
10

They are synonyms, no difference at all.

At least on SQL Server in the ANSI SQL standards. This SO answer shows some difference in ANSI but I suspect in implementation they are the same

于 2009-12-03T18:33:22.147 回答
5

Postgres: 没有区别

在表 8.1 中的文档描述中看起来相同,但没有解释为什么单独提到它,所以根据 Tom Lane的帖子

在 Postgres 中没有任何区别。有两种类型名称,因为 SQL 标准要求我们接受这两种名称。快速浏览一下标准,似乎唯一的区别是:

     17)NUMERIC specifies the data type exact numeric, with the decimal
        precision and scale specified by the <precision> and <scale>.

     18)DECIMAL specifies the data type exact numeric, with the decimal
        scale specified by the <scale> and the implementation-defined
        decimal precision equal to or greater than the value of the
        specified <precision>.

即,对于 DECIMAL,实现允许在小数点左侧允许比请求更多的数字。Postgres 不行使这种自由,因此对我们来说这些类型之间没有区别。

      regards, tom lane

还有一个页面较低的文档清楚地说明,

十进制和数字类型是等价的。这两种类型都是 SQL 标准的一部分。

并且在别名表 decimal [ (p, s) ]中也提到了别名numeric [ (p, s) ]

于 2016-11-08T14:51:56.373 回答
2

它们实际上是等价的,但它们是独立的类型,而不是技术上的同义词,如 ROWVERSION 和 TIMESTAMP - 尽管它们可能曾经在文档中被称为同义词。这是同义词的稍微不同的含义(例如,除了名称之外,它们无法区分,没有一个是另一个的别名)。很讽刺,对吧?

我从 MSDN 中的措辞实际上是: 这些类型是相同的,只是名称不同。

除了 type_id 值之外,这里的所有内容都是相同的:

SELECT * FROM sys.types WHERE name IN (N'numeric', N'decimal');

我完全不知道两者之间的任何行为差异,并且回到 SQL Server 6.5,一直将它们视为 100% 可互换。

for DECIMAL(18,2) and NUMERIC(18,2)? Assigning one to the other is technically a "conversion"?

仅当您明确这样做时。您可以通过创建一个表然后检查查询计划以查找执行显式或(您可能期望的)隐式转换的查询来轻松证明这一点。这是一个简单的表格:

    CREATE TABLE [dbo].[NumDec]
(
    [num] [numeric](18, 0) NULL,
    [dec] [decimal](18, 0) NULL
);

现在运行这些查询并捕获计划:

DECLARE @num NUMERIC(18,0);
DECLARE @dec DECIMAL(18,0);

    SELECT 
      CONVERT(DECIMAL(18,0), [num]), -- conversion
      CONVERT(NUMERIC(18,0), [dec])  -- conversion
    FROM dbo.NumDec
    UNION ALL SELECT [num],[dec] 
      FROM dbo.NumDec WHERE [num] = @dec  -- no conversion
    UNION ALL SELECT [num],[dec] 
      FROM dbo.NumDec WHERE [dec] = @num; -- no conversion

我们在我们要求的地方有明确的转换,但在我们可能期望的地方没有明确的转换。似乎优化器也将它们视为可互换的。

就个人而言,我更喜欢使用 DECIMAL 一词,因为它更准确且更具描述性。BIT 也是“数字”的。

于 2018-11-17T07:01:02.980 回答