J'utilise une colonne décimale pour stocker les valeurs monétaires sur une base de données, et aujourd'hui je me demandais quelle précision et quelle échelle utiliser.
Étant donné que les colonnes supposées char d'une largeur fixe sont plus efficaces, je pensais que la même chose pourrait être vraie pour les colonnes décimales. C'est ça?
Et quelle précision et quelle échelle dois-je utiliser? Je pensais précision 24/8. Est-ce exagéré, insuffisant ou correct?
Voici ce que j'ai décidé de faire:
- Stockez les taux de conversion (le cas échéant) dans la table de transaction elle-même, sous forme de flottant
- Stocker la devise dans la table de compte
- Le montant de la transaction sera un
DECIMAL(19,4)
- Tous les calculs utilisant un taux de conversion seront gérés par mon application afin que je garde le contrôle des problèmes d'arrondi
Je ne pense pas qu'un flottant pour le taux de conversion soit un problème, car c'est principalement à titre de référence, et je vais de toute façon le convertir en décimale.
Merci à tous pour votre précieuse contribution.
DECIMAL(19, 4)
est un choix populaire vérifier ceci également vérifier ici World Currency Formats pour décider du nombre de décimales à utiliser, l'espoir vous aidera.Réponses:
Si vous recherchez une taille unique, je suggère que ce
DECIMAL(19, 4)
soit un choix populaire (un rapide Google le confirme). Je pense que cela provient de l'ancien type de données VBA / Access / Jet Currency, étant le premier type décimal à virgule fixe dans la langue;Decimal
seulement venu dans le style «version 1.0» (c'est-à-dire pas entièrement implémenté) dans VB6 / VBA6 / Jet 4.0.La règle de base pour le stockage des valeurs décimales à virgule fixe est de stocker au moins une décimale de plus que ce dont vous avez réellement besoin pour permettre l'arrondi. L'une des raisons de mapper l'ancien
Currency
type dans le front-end auDECIMAL(19, 4)
type dans le back-end était que lesCurrency
banquiers étaient arrondis par nature, alors queDECIMAL(p, s)
arrondis par troncature.Une décimale supplémentaire dans le stockage pour
DECIMAL
permet à un algorithme d'arrondi personnalisé d'être implémenté plutôt que de prendre la valeur par défaut du fournisseur (et l'arrondi des banquiers est alarmant, c'est le moins qu'on puisse dire, pour un concepteur qui s'attend à ce que toutes les valeurs se terminant par 0,5 arrondissent à zéro) .Oui,
DECIMAL(24, 8)
ça me semble exagéré. La plupart des devises sont cotées avec quatre ou cinq décimales. Je connais des situations où une échelle décimale de 8 (ou plus) est requise, mais c'est là qu'un montant monétaire `` normal '' (disons quatre décimales) a été au prorata, ce qui implique que la précision décimale doit être réduite en conséquence (considérez également un type à virgule flottante dans de telles circonstances). Et personne n'a autant d'argent aujourd'hui pour exiger une précision décimale de 24 :)Cependant, au lieu d'une approche universelle, certaines recherches peuvent s'avérer nécessaires. Renseignez-vous auprès de votre concepteur ou expert du domaine sur les règles comptables qui peuvent être applicables: GAAP, UE, etc. Je me souviens vaguement de certains transferts intra-étatiques de l'UE avec des règles explicites pour arrondir à cinq décimales, donc utiliser
DECIMAL(p, 6)
pour le stockage. Les comptables semblent généralement privilégier quatre décimales.PS Évitez le
MONEY
type de données de SQL Server car il a de sérieux problèmes de précision lors de l'arrondi, entre autres considérations telles que la portabilité, etc. Voir le blog d'Aaron Bertrand .Microsoft et les concepteurs de langage ont choisi l'arrondissement des banquiers parce que les concepteurs de matériel l'ont choisi [citation?]. Il est par exemple inscrit dans les normes de l'Institut des ingénieurs électriciens et électroniciens (IEEE). Et les concepteurs de matériel l'ont choisi parce que les mathématiciens le préfèrent. Voir Wikipedia ; pour paraphraser: L'édition 1906 de Probability and Theory of Error appelait cela «la règle de l'ordinateur» («ordinateurs» signifiant les humains qui effectuent des calculs).
la source
DECIMAL(19, 4)
plus populaire queDECIMAL(19, 2)
? La plupart des devises mondiales ne comportent que deux décimales.Nous avons récemment mis en œuvre un système qui doit gérer les valeurs dans plusieurs devises et effectuer une conversion entre elles, et nous avons résolu certaines choses à la dure.
NE JAMAIS UTILISER DE NUMÉROS DE POINTS FLOTTANTS POUR DE L'ARGENT
L'arithmétique en virgule flottante introduit des inexactitudes qui peuvent ne pas être remarquées tant qu'ils n'ont pas foiré quelque chose. Toutes les valeurs doivent être stockées sous forme d'entiers ou de types décimaux fixes, et si vous choisissez d'utiliser un type décimal fixe, assurez-vous de comprendre exactement ce que fait ce type sous le capot (c'est-à-dire, utilise-t-il en interne un entier ou une virgule flottante type).
Lorsque vous devez effectuer des calculs ou des conversions:
Lors de la conversion d'un nombre à virgule flottante en un entier à l'étape 3, ne vous contentez pas de le convertir - utilisez une fonction mathématique pour l'arrondir en premier. Ce sera généralement le cas
round
, bien que dans des cas particuliers, cela puisse êtrefloor
ouceil
. Connaissez la différence et choisissez avec soin.Stocker le type d'un nombre à côté de la valeur
Cela peut ne pas être aussi important pour vous si vous ne manipulez qu'une seule devise, mais c'était important pour nous dans le traitement de plusieurs devises. Nous avons utilisé le code à 3 caractères pour une devise, telle que USD, GBP, JPY, EUR, etc.
Selon la situation, il peut également être utile de stocker:
Connaissez les limites de précision des nombres avec lesquels vous traitez
Pour les valeurs réelles, vous voulez être aussi précis que la plus petite unité de la devise. Cela signifie que vous n'avez pas de valeurs inférieures à un cent, un centime, un yen, un fen, etc. Ne stockez pas les valeurs avec une précision plus élevée que cela sans raison.
En interne, vous pouvez choisir de traiter des valeurs plus petites, auquel cas il s'agit d'un type de valeur de devise différent . Assurez-vous que votre code sait lequel est lequel et ne les confond pas. Évitez d'utiliser des valeurs à virgule flottante même ici.
En ajoutant toutes ces règles ensemble, nous avons décidé des règles suivantes. Dans le code en cours d'exécution, les devises sont stockées en utilisant un entier pour la plus petite unité.
Dans la base de données, les valeurs sont stockées sous forme de chaîne au format suivant:
Cela stocke la valeur de 25,00 $. Nous avons pu le faire uniquement parce que le code qui traite des devises n'a pas besoin d'être dans la couche de base de données elle-même, de sorte que toutes les valeurs peuvent être converties en mémoire en premier. D'autres situations se prêteront sans doute à d'autres solutions.
Et au cas où je ne l'ai pas précisé plus tôt, n'utilisez pas de flotteur!
la source
bigint
si vous avez l'intention de trier par montant. Et ne perdez pas votre temps avec PHP 32 bits lorsque vous traitez avec de gros entiers, passez à 64 bits ou Node.JS;)Lorsque vous manipulez de l'argent dans MySQL, utilisez DECIMAL (13,2) si vous connaissez la précision de vos valeurs d'argent ou utilisez DOUBLE si vous voulez juste une valeur approximative rapide assez bonne. Donc, si votre application doit gérer des valeurs monétaires allant jusqu'à un billion de dollars (ou euros ou livres), cela devrait fonctionner:
Ou, si vous devez vous conformer aux PCGR, utilisez:
la source
4 décimales vous donneraient la précision de stocker les plus petites sous-unités monétaires du monde. Vous pouvez le réduire davantage si vous avez besoin d'une précision de micropaiement (nanopaiement?!).
Moi aussi, je préfère
DECIMAL
les types d'argent spécifiques aux SGBD, vous êtes plus sûr de garder ce genre de logique dans l'application IMO. Une autre approche dans le même sens consiste simplement à utiliser un entier [long], avec un formatage en ¤unit.subunit pour une lisibilité humaine (¤ = symbole monétaire) effectué au niveau de l'application.la source
Le type de données money sur SQL Server comporte quatre chiffres après la virgule.
À partir de la documentation en ligne de SQL Server 2000:
Les données monétaires représentent des montants d'argent positifs ou négatifs. Dans Microsoft® SQL Server ™ 2000, les données monétaires sont stockées à l'aide des types de données money et smallmoney. Les données monétaires peuvent être stockées avec une précision de quatre décimales. Utilisez le type de données money pour stocker des valeurs comprises entre -922 337 203 685 477,5808 et +922 337 203 685 477,5807 (nécessite 8 octets pour stocker une valeur). Utilisez le type de données smallmoney pour stocker des valeurs comprises entre -214 748,3648 et 214 748,3647 (nécessite 4 octets pour stocker une valeur). Si un plus grand nombre de décimales est requis, utilisez plutôt le type de données décimal.
la source
Parfois, vous devrez aller à moins d'un cent et il y a des devises internationales qui utilisent de très grandes démoniations. Par exemple, vous pouvez facturer à vos clients 0,088 centimes par transaction. Dans ma base de données Oracle, les colonnes sont définies comme NUMBER (20,4)
la source
Si vous envisagez d'effectuer des opérations arithmétiques dans la base de données (multipliant les taux de facturation, etc.), vous voudrez probablement beaucoup plus de précision que ce que les gens suggèrent ici, pour les mêmes raisons que vous ne souhaitez utiliser une valeur inférieure à une valeur à virgule flottante double précision dans le code d'application.
la source
BigDecimal
), mais pendant longtemps, c'était la double précision (pensezdouble
au lieu defloat
). En outre, la précision arbitraire entraîne des pénalités de performances significatives dans certains cas. Le test est définitivement la bonne approche.Si vous utilisiez IBM Informix Dynamic Server, vous auriez un type MONEY qui est une variante mineure du type DECIMAL ou NUMERIC. C'est toujours un type à virgule fixe (alors que DECIMAL peut être un type à virgule flottante). Vous pouvez spécifier une échelle de 1 à 32 et une précision de 0 à 32 (par défaut, une échelle de 16 et une précision de 2). Ainsi, en fonction de ce que vous devez stocker, vous pouvez utiliser DECIMAL (16,2) - encore assez grand pour contenir le déficit fédéral américain, au cent près - ou vous pouvez utiliser une plage plus petite ou plus de décimales.
la source
Je pense que dans une large mesure, vos exigences ou celles de votre client devraient dicter la précision et l'échelle à utiliser. Par exemple, pour le site Web de commerce électronique sur lequel je travaille et qui traite uniquement de l'argent en GBP, j'ai été obligé de le maintenir à Decimal (6, 2).
la source
Une réponse tardive ici, mais j'ai utilisé
ce que j'ai raison de penser devrait permettre jusqu'à 99 999 999 999,99.
la source