Разница между десятичным и числовым - PullRequest
43 голосов
/ 03 декабря 2009

В чем разница между типом данных SQL NUMERIC и DECIMAL? Если базы данных обрабатывают их по-разному, я хотел бы знать, как минимум:

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

Кроме того, есть ли различия в том, как драйверы баз данных интерпретируют эти типы?

Ответы [ 4 ]

36 голосов
/ 03 декабря 2009

Они одинаковы практически для всех целей.

Когда-то разные продавцы использовали разные имена (числовые / десятичные) для почти одного и того же. SQL-92 сделал их одинаковыми с одним небольшим отличием, которое может зависеть от поставщика:

NUMERIC должен быть точно таким же точным, как он определен - поэтому, если вы определяете 4 десятичных знака, БД всегда должна хранить 4 десятичных знака.

DECIMAL должно быть как минимум настолько точно, насколько это определено. Это означает, что база данных может хранить больше цифр, чем указано (из-за того, что в закулисном хранилище есть место для дополнительных цифр). Это означает, что база данных может хранить 1.00005 вместо 1.0000, что влияет на будущие вычисления.

В SQL Server числовой определяется как идентичный десятичному во всех отношениях - оба всегда будут хранить только указанное количество десятичных знаков.

8 голосов
/ 03 декабря 2009

Это синонимы, вообще без разницы.

Как минимум на SQL Server в стандартах ANSI SQL. Этот SO ответ показывает некоторую разницу в ANSI, но я подозреваю, что в реализации они совпадают

4 голосов
/ 08 ноября 2016

Postgres: Без разницы

в документации описание в таблице 8.1 выглядит одинаково, но не объясняется, почему оно упоминается отдельно, поэтому по словам Тома Лейна сообщение

Там нет никакой разницы, в 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 реализация может допускать большее количество цифр чем запрашивается слева от десятичной точки. Постгрес не осуществлять эту свободу, так что нет никакой разницы между этими типами для нам.

      regards, tom lane

также на страницу ниже документы ясно указывают, что

Типы десятичные и числовые эквивалентны. Оба типа являются частью стандарт SQL.

а также в таблица псевдонимов decimal [ (p, s) ] упоминается как псевдоним для numeric [ (p, s) ]

1 голос
/ 17 ноября 2018

Они на самом деле эквивалентны, но они являются независимыми типами, а не технически синонимами, такими как 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 только потому, что он гораздо более точный и описательный. БИТ тоже "числовой".

...