web-dev-qa-db-fra.com

Différence entre DECIMAL et NUMERIC

Quelle est la différence entre le type de données SQL NUMERIC et DECIMAL? Si les bases de données les traitent différemment, j'aimerais savoir comment au moins:

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

En outre, existe-t-il des différences dans la façon dont les pilotes de base de données interprètent ces types?

45
leeeroy

Ils sont les mêmes pour presque tous les usages.

À une époque, différents fournisseurs utilisaient des noms différents (numérique/décimal) pour presque la même chose. SQL-92 les a rendus identiques avec une différence mineure qui peut être spécifique au fournisseur:

NUMERIC doit être exactement aussi précis qu'il est défini - donc si vous définissez 4 décimales, la base de données doit toujours stocker 4 décimales.

DECIMAL doit être au moins aussi précis qu'il est défini. Cela signifie que la base de données peut réellement stocker plus de chiffres que spécifié (en raison du stockage en arrière-plan ayant de l'espace pour des chiffres supplémentaires). Cela signifie que la base de données peut stocker 1.00005 au lieu de 1.0000, affectant les calculs futurs.

Dans SQL Server, Numeric est défini comme étant identique à Decimal dans tous les sens - les deux ne stockent toujours que le nombre spécifié de décimales.

39
David

Ce sont des synonymes, pas de différence du tout.

Au moins sur SQL Server dans les normes ANSI SQL. Cette SO réponse montre une certaine différence dans ANSI mais je suppose que dans la mise en œuvre, ils sont les mêmes

9
gbn

Postgres: Aucune différence

dans documentation la description dans le tableau 8.1 est la même, mais il n'est pas expliqué pourquoi elle est mentionnée séparément, donc selon Tom Lane post

Il n'y a aucune différence, à Postgres. Il existe deux noms de types car la norme SQL nous oblige à accepter les deux noms. En un coup d'œil dans la norme, il apparaît que la seule différence est la suivante:

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

c'est-à-dire que pour DECIMAL, l'implémentation est autorisée à autoriser plus de chiffres que demandé à gauche du séparateur décimal. Postgres n'exerce pas cette liberté, il n'y a donc pas de différence entre ces types pour nous.

      regards, tom lane

également une page inférieure docs énoncez clairement que

Les types décimal et numérique sont équivalents. Les deux types font partie de la norme SQL.

et aussi à table d'aliasdecimal [ (p, s) ] est mentionné comme alias pour numeric [ (p, s) ]

5
Vao Tsun

Ils sont en fait équivalents, mais ce sont des types indépendants, et non des synonymes techniques, comme ROWVERSION et TIMESTAMP - bien qu'ils puissent avoir été appelés synonymes dans la documentation à un moment donné. C'est un sens légèrement différent du synonyme (par exemple, ils ne peuvent être distingués que par leur nom, aucun n'est un alias pour l'autre). Ironique, non?

Ce que j'interprète à partir du libellé de MSDN est en fait: Ces types sont identiques, ils ont juste des noms différents.

À part les valeurs type_id, tout ici est identique:

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

Je n'ai absolument aucune connaissance des différences de comportement entre les deux, et pour en revenir à SQL Server 6.5, je les ai toujours traités comme 100% interchangeables.

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

Seulement si vous le faites explicitement. Vous pouvez le prouver facilement en créant une table puis en inspectant le plan de requête pour les requêtes qui effectuent des conversions explicites ou - vous pourriez vous y attendre - implicites. Voici un tableau simple:

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

Exécutez maintenant ces requêtes et capturez le 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

nous avons des conversions explicites là où nous les avons demandées, mais aucune conversion explicite là où nous aurions pu les attendre. Il semble que l'optimiseur les traite également comme interchangeables.

Personnellement, je préfère utiliser le terme DECIMAL simplement parce qu'il est beaucoup plus précis et descriptif. Le BIT est également "numérique".

1
Coder Girl