DECIMAL 和 NUMERIC 之间的区别

发布于 2024-08-13 04:53:13 字数 234 浏览 9 评论 0原文

SQL 数据类型 NUMERICDECIMAL 之间有什么区别? 如果数据库以不同的方式对待这些类型,我想知道至少如何:

  • SQL Server
  • Oracle
  • Db/2
  • MySQL
  • PostgreSQL

此外,数据库驱动程序解释这些类型的方式是否有任何差异?

What's the difference between the SQL datatype NUMERIC and DECIMAL ?
If databases treat these differently, I'd like to know how for at least:

  • SQL Server
  • Oracle
  • Db/2
  • MySQL
  • PostgreSQL

Furthermore, are there any differences in how database drivers interpret these types?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

清风不识月 2024-08-20 04:53:13

它们几乎在所有用途上都是相同的。

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

NUMERIC 必须与定义的一样精确 - 因此,如果将其定义为总共 8 位数字,小数点后 4 位为在小数点右侧,DB 必须始终存储 (8, 4) 位小数,不能多也不能少。

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

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

They are the same for almost all purposes.

At one time different vendors used different names (NUMERIC/DECIMAL) for almost the same thing. SQL-92 made them the same with one minor difference which can be vendor specific:

NUMERIC must be exactly as precise as it is defined — so if you define it as 8 total digits with 4 decimal places to the right of the decimal point, the DB must always store (8, 4) decimal places, no more, no less.

DECIMAL is free to allow higher numbers if that's easier to implement. This means that the database can actually store more digits than specified (due to the behind-the-scenes storage having space for extra digits). This means the database might allow storing 12345.0000 in the above example of (8, 4) decimal places, but storing 1.00005 is still not allowed if doing so could affect any future calculations.

Most current database systems treat DECIMAL and NUMERIC either as perfect synonyms, or as two distinct types with exactly the same behavior. If the types are considered distinct at all, you might not be able to define a foreign key constrain on a DECIMAL column referencing a NUMERIC column or vice versa.

水染的天色ゝ 2024-08-20 04:53:13

它们是同义词,没有任何区别。

至少在 SQL Server 上符合 ANSI SQL 标准。
这个所以答案显示 ANSI 中有些差异,但我怀疑在实现上它们是相同的

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

小镇女孩 2024-08-20 04:53:13

Postgres: 没有区别

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

没有任何区别,
Postgres。有两个类型名称,因为 SQL 标准要求
我们接受这两个名字。快速浏览一下标准就会发现
唯一的区别是:

 17)NUMERIC 指定数据类型精确数字,带小数
        < precision> 指定的精度和小数位数和<比例>。

     18)DECIMAL指定数据类型精确数值,带小数
        由  指定的比例和实现定义的
        小数精度等于或大于该值
        指定<精度>。

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

问候,汤姆·莱恩

下一页 docs 清楚地表明,

decimal 和 numeric 类型是等效的。这两种类型都是
SQL 标准。

以及 别名表 十进制 [ (p, s) ] 被提及为数字 [ (p, s) ] 的别名

Postgres: No difference

in documentation description in table 8.1 looks same, yet it is not explained why it is mentioned separately, so
according to Tom Lane post

There isn't any difference, in
Postgres. There are two type names because the SQL standard requires
us to accept both names. In a quick look in the standard it appears
that the only difference is this:

     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>.

ie, for DECIMAL the implementation is allowed to allow more digits
than requested to the left of the decimal point. Postgres doesn't
exercise that freedom so there's no difference between these types for
us.

      regards, tom lane

also a page lower docs state clearly, that

The types decimal and numeric are equivalent. Both types are part of
the SQL standard.

and also at aliases table decimal [ (p, s) ] is mentioned as alias for numeric [ (p, s) ]

且行且努力 2024-08-20 04:53:13

它们实际上是等价的,但它们是独立的类型,并且在技术上不是同义词,例如 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 也是“数字”。

They are actually equivalent, but they are independent types, and not technically synonyms, like ROWVERSION and TIMESTAMP - though they may have been referred to as synonyms in the documentation at one time. That is a slightly different meaning of synonym (e.g. they are indistinguishable except in name, not one is an alias for the other). Ironic, right?

What I interpret from the wording in MSDN is actually:
These types are identical, they just have different names.

Other than the type_id values, everything here is identical:

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

I have absolutely no knowledge of any behavioral differences between the two, and going back to SQL Server 6.5, have always treated them as 100% interchangeable.

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

Only if you do so explicitly. You can prove this easily by creating a table and then inspecting the query plan for queries that perform explicit or - you might expect - implicit conversions. Here's a simple table:

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

Now run these queries and capture the plan:

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

we have explicit conversions where we asked for them, but no explicit conversions where we might have expected them. Seems the optimizer is treating them as interchangeable, too.

Personally, I prefer to use the term DECIMAL just because it's much more accurate and descriptive. BIT is "numeric" too.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文