web-dev-qa-db-fra.com

Meilleur type de données pour stocker les valeurs monétaires dans une base de données MySQL

Quel est le meilleur type de données SQL pour les valeurs monétaires? J'utilise MySQL mais préférerais un type indépendant de la base de données.

201
Brian Fisher

Quelque chose comme Decimal(19,4) fonctionne généralement plutôt bien dans la plupart des cas. Vous pouvez ajuster l'échelle et la précision pour répondre aux besoins des nombres que vous devez stocker. Même dans SQL Server, j’ai tendance à ne pas utiliser "money" car il n’est pas standard.

222
Kibbee

La seule chose à surveiller est que si vous migrez d'une base de données à une autre, vous constaterez peut-être que DECIMAL (19,4) et DECIMAL (19,4) ont une signification différente.

( http://dev.mysql.com/doc/refman/5.1/en/precision-math-decimal-changes.html )

 DBASE: 10,5 (entier, 5 décimal) 
 MYSQL: 15,5 (15 chiffres, 10 entiers (15-5), 5 décimales) 
47
SeanJA

Réponse d'Assaf de 

Cela dépend de combien d'argent vous avez ...

cela semble désinvolte, mais en réalité, il est pertinent.

Seulement aujourd'hui, nous avons eu un problème où un enregistrement n'a pas pu être inséré dans notre table de taux, car l'une des colonnes (GrossRate) est définie sur Decimal (11,4), et notre service des produits vient de signer un contrat pour des chambres dans un superbe complexe à Bora Bora, qui se vendent plusieurs millions de francs par nuit, ce qui n’a jamais été anticipé lors de la conception du schéma de la base de données, il ya 10 ans.

17
Scott Ferguson

Il est également important de déterminer le nombre de décimales nécessaires pour vos calculs. 

J'ai travaillé sur une application du prix des actions qui nécessitait le calcul du prix d'un million d'actions. Le prix de l'action coté devait être enregistré avec une précision de 7 chiffres.

17
Leah

Pour les applications de comptabilité, il est très courant de stocker les valeurs sous forme de nombres entiers (certains vont même jusqu'à dire que c'est le seulement way). Pour avoir une idée, prenons le montant des transactions (supposons 100,23 $) et multipliez-le par 100, 1 000, 10 000, etc. pour obtenir l'exactitude dont vous avez besoin. Donc, si vous avez seulement besoin de stocker des centimes et que vous pouvez arrondir en toute sécurité, multipliez-les par 100. Dans mon exemple, cela ferait 10023 comme nombre entier à stocker. Vous gagnerez de la place dans la base de données et la comparaison de deux entiers est beaucoup plus facile que la comparaison de deux flottants. Mon 0,02 $.

10
Dane Bendixen

entrée très tardive mais les PCGR sont une bonne règle de base ..

Si votre application doit gérer des valeurs monétaires allant jusqu'à un billion de dollars, cela devrait fonctionner: 13,2 Si vous devez respecter les principes comptables généralement reconnus (GAAP), utilisez: 13,4

Habituellement, vous devez additionner vos valeurs monétaires à 13,4 avant d’arrondir la sortie à 13,2.

Source: Meilleur type de données pour stocker une valeur monétaire dans MySQL

8
Damian

Vous pouvez utiliser par défaut quelque chose comme DECIMAL(19,2) pour toutes vos valeurs monétaires, mais si vous ne stockez que des valeurs inférieures à 1 000 dollars, vous perdrez un espace précieux dans la base de données.

Pour la plupart des implémentations, DECIMAL(N,2) serait suffisant, où la valeur de N est au moins égale au nombre de chiffres précédant le . de la plus grande somme que vous vous attendiez à stocker dans ce champ + 5. Donc, si vous ne comptez jamais stocker des valeurs supérieures à 999999,99 $, DECIMAL(11,2) devrait être plus que suffisant (jusqu'à ce que les attentes changent).

Si vous voulez être conforme à GAAP , vous pouvez utiliser DECIMAL(N,4), où la valeur de N est au moins égale au nombre de chiffres précédant le . de la somme maximale dans laquelle vous vous attendez à être stockée. ce champ + 7.

5
John Slegers

Cela dépend de la nature des données. Vous devez le contempler à l'avance. 

Mon cas

  • décimal (13,4) non signé pour l'enregistrement des transactions en argent
    • stockage efficace (4 octets pour chaque côté du point décimal quand même) 1
    • Conforme aux normes GAAP 
  • décimal (19,4) non signé pour les agrégats
    • nous avons besoin de plus d'espace pour les totaux de plusieurs transactions de plusieurs milliards
    • semi-conformité avec le type de données MS Currency ne fera pas mal 2
    • il faudra plus d'espace par enregistrement (11 octets - 7 à gauche et 4 à droite), mais c'est correct car il y a moins d'enregistrements pour les agrégats 1
  • décimale (10,5) pour les taux de change
    • ils sont normalement cités avec 5 chiffres au total afin que vous puissiez trouver des valeurs comme 1.2345 & 12.345 mais pas 12345.67890
    • c'est une convention répandue, mais pas une norme codifiée (du moins à ma connaissance de recherche rapide)
    • vous pouvez le rendre décimal (18,9) avec le même stockage, mais les restrictions de type de données constituent un précieux mécanisme de validation intégré

Pourquoi (M, 4)?

  • il y a des devises qui se divisent en mille centimes 
  • il existe des équivalents monétaires tels que "Unidad de Fermento", "CLF", exprimés avec 4 décimales significatives 3 , 4
  • il est conforme aux PCGR

Troquer

  • précision inférieure:
    • moindre coût de stockage
    • calculs plus rapides
    • risque d'erreur de calcul réduit
    • sauvegarde et restauration plus rapides
  • précision supérieure:
    • compatibilité future (les nombres ont tendance à augmenter)
    • gain de temps de développement (vous n'aurez pas à reconstruire la moitié d'un système lorsque les limites sont atteintes)
    • risque réduit d'échec de la production dû à une précision de stockage insuffisante

Compatible Extreme

Bien que MySQL vous permette d'utiliser decimal (65,30), 31 pour l'échelle et 30 pour la précision semblent être nos limites si nous voulons laisser l'option de transfert ouverte.

Échelle et précision maximales dans les SGBDR les plus courants:

 Precision Scale
Oracle 31 31 
 T-SQL 38 38 
 MySQL 65 30 
 PostgreSQL 131072 16383 

6 , 7 , 8 , 9

Extrême raisonnable

  1. Pourquoi (27,4)?
    • on ne sait jamais quand le système doit stocker des dollars zimbabwéens

Septembre 2015 Le gouvernement zimbabwéen a déclaré qu'il échangerait des dollars zimbabwéens en dollars américains à un taux de change allant de 1 USD à 35 quadrillions de dollars zimbabwéens 5

Nous avons tendance à dire "oui, bien sûr ... je n'aurai pas besoin de ces chiffres fous". Eh bien, les Zimbabwéens avaient l'habitude de dire cela aussi. Il n'y a pas longtemps.

Imaginons que vous deviez enregistrer une transaction de 1 million USD en dollars zimbabwéens (peut-être peu probable aujourd'hui, mais qui sait à quoi cela ressemblera dans 10 ans?). 

  1. (1 million USD) * (35 Quadrylion ZWL) = (10 ^ 6) * (35 * 10 ^ 15) = 35 * 10 ^ 21
  2. nous avons besoin:
    • 2 chiffres pour stocker "35"
    • 21 chiffres pour stocker les zéros
    • 4 chiffres à la droite du point décimal
  3. cela donne un nombre décimal (27,4) qui nous coûte 15 octets pour chaque entrée
  4. nous pouvons ajouter un chiffre supplémentaire à gauche sans frais - nous avons décimal (28,4) pour 15 octets 
  5. Nous pouvons maintenant stocker une transaction de 10 millions de dollars US exprimée en dollars zimbabwéens ou nous protéger d'une autre frappe d'hiperinflation, ce qui, espérons-le, n'aura pas lieu
2
kshishkin

Bien que cela puisse être en retard, mais cela sera utile à quelqu'un d'autre. De mon expérience et de mes recherches, je suis parvenu à connaître et accepter le nombre décimal (19, 6). lorsque vous travaillez avec une grande quantité d'argent et un taux de change

0
precious