Question

J'utilise une colonne décimale pour stocker des valeurs monétaires dans une base de données. Aujourd'hui, je me demandais quelle précision et quelle échelle utiliser.

Etant donné que les colonnes censées avoir une largeur fixe sont plus efficaces, je pensais qu'il en allait de même pour les colonnes décimales. Est-ce?

Et quelle précision et quelle échelle devrais-je utiliser? Je pensais à la précision 24/8. Est-ce excessif, pas assez ou bien?

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 valeur flottante
  • Stocker la devise dans la table des comptes
  • Le montant de la transaction sera un DECIMAL (19,4)
  • Tous les calculs utilisant un taux de conversion seront traité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 il est principalement utilisé à titre de référence, et je le mettrai quand même en décimal.

Merci à tous pour votre précieuse contribution.

Était-ce utile?

La solution

Si vous recherchez une solution unique, je suggérerais que 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, le premier type décimal à virgule fixe de la langue; Decimal est uniquement venu dans le style "version 1.0" (c’est-à-dire qu’il n’a pas été 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 supplémentaire par rapport au nombre requis pour permettre l'arrondi. Une des raisons pour associer l'ancien type Currency du frontal à un DECIMAL (19, 4) du type back-end était que Currency arrondi des banquiers exposés par nature, alors que DECIMAL (p, s) est arrondi par la troncature.

Une décimale supplémentaire dans la mémoire de DECIMAL permet de mettre en œuvre un algorithme d'arrondi personnalisé plutôt que de prendre la valeur par défaut du fournisseur (et l'arrondi des banquiers est pour le moins alarmant, pour un concepteur qui attend tout. valeurs se terminant par 0,5 pour arrondir à zéro).

Oui, DECIMAL (24, 8) me semble excessif. La plupart des devises sont citées à quatre ou cinq décimales. Je connais des situations dans lesquelles une échelle décimale de 8 (ou plus) est requise, mais c’est dans ce cas qu’un montant monétaire «normal» (par exemple à quatre décimales) a été calculé, ce qui implique une précision décimale. devrait être réduite en conséquence (envisagez également un type à virgule flottante dans de telles circonstances). Et personne n’a autant d’argent pour exiger une précision décimale de 24:)

Cependant, plutôt que d’adopter une approche unique, certaines recherches pourraient être en ordre. Demandez à votre concepteur ou à votre expert de domaine les règles de comptabilité pouvant être applicables: GAAP, UE, etc. Je me souviens vaguement de certains transferts intra-États de l'UE avec des règles explicites pour arrondir à cinq décimales, donc avec DECIMAL (p, 6) pour le stockage. Les comptables semblent généralement privilégier quatre décimales.

PS Évitez le type de données MONEY de SQL Server, car il a de sérieux problèmes de précision lors de l'arrondissement, entre autres considérations telles que la portabilité, etc. Voir Le blog de Aaron Bertrand .

Microsoft et les concepteurs linguistiques ont choisi l'arrondissement bancaire parce que les concepteurs de matériel l'ont choisi [citation?]. Il est inscrit dans les normes de l'Institut des ingénieurs électriciens et électroniciens (IEEE), par exemple. Et les concepteurs de matériel l'ont choisi parce que les mathématiciens le préfèrent. Voir Wikipedia ; pour paraphraser: L'édition de 1906 de Probabilités et théorie des erreurs appelait cela la "règle de l'ordinateur" ("ordinateurs", signifiant des humains effectuant des calculs).

Autres conseils

Nous avons récemment mis en place un système qui doit gérer les valeurs dans plusieurs devises et effectuer des conversions entre celles-ci. Nous avons compris certaines choses à la dure.

N'UTILISEZ JAMAIS 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 jusqu'à ce qu'elles aient foiré quelque chose. Toutes les valeurs doivent être stockées sous forme d’entiers ou de types décimaux fixes. Si vous choisissez d’utiliser un type décimal fixe, assurez-vous de bien comprendre ce que ce type fait sous le capot (c’est-à-dire qu’il utilise en interne un entier ou une virgule flottante. type).

Lorsque vous devez effectuer des calculs ou des conversions:

  1. Conversion des valeurs en virgule flottante
  2. Calculer la nouvelle valeur
  3. Arrondissez le nombre et reconvertissez-le en entier

Lors de la conversion d'un nombre à virgule flottante en un entier à l'étape 3, ne le convertissez pas simplement - utilisez une fonction mathématique pour le arrondir en premier. Ce sera généralement round , bien que dans des cas particuliers, il puisse s'agir de floor ou de ceil . 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 gérez qu'une seule devise, mais cela a été important pour nous dans la gestion 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:

  • Si le nombre est avant ou après impôt (et quel était le taux d'imposition)
  • Si le nombre est le résultat d'une conversion (et de quoi il a été converti)

Connaissez les limites de précision des chiffres 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 aucune valeur inférieure à un cent, un sou, un yen, un fen, etc. Ne stockez pas les valeurs avec une précision supérieure à celle-ci sans raison.

En interne, vous pouvez choisir de traiter des valeurs plus petites, auquel cas il s’agit d’un type de valeur monétaire différent . Assurez-vous que votre code sait lequel est lequel et ne les mélange pas. Évitez d’utiliser des valeurs en virgule flottante même ici.

En additionnant toutes ces règles, nous avons choisi les règles suivantes. En code courant, les devises sont stockées en utilisant un entier pour la plus petite unité.

class Currency {
   String code;       //  eg "USD"
   int value;         //  eg 2500
   boolean converted;
}

class Price {
   Currency grossValue;
   Currency netValue;
   Tax taxRate;
}

Dans la base de données, les valeurs sont stockées sous forme de chaîne au format suivant:

USD:2500

Cela stocke la valeur de 25,00 $. Nous n'avons pu le faire que parce que le code traitant des devises ne doit pas nécessairement se trouver dans la couche de base de données, de sorte que toutes les valeurs peuvent d'abord être converties en mémoire. D’autres situations se prêteront sans doute à d’autres solutions.

Et au cas où je ne l'aurais pas dit plus tôt, n'utilisez pas de float!

Lorsque vous manipulez de l’argent dans MySQL, utilisez DECIMAL (13,2) si vous connaissez la précision de vos valeurs monétaires ou utilisez DOUBLE si vous souhaitez simplement obtenir une valeur approximative rapide et satisfaisante. Par conséquent, si votre application doit gérer des valeurs monétaires allant jusqu'à un billion de dollars (ou en euros ou en livres sterling), cela devrait alors fonctionner:

DECIMAL(13, 2)

Ou, si vous devez vous conformer aux PCGR , utilisez:

DECIMAL(13, 4)

Quatre décimales vous donneraient la précision nécessaire pour stocker les plus petites sous-unités monétaires du monde. Vous pouvez le réduire davantage si vous avez besoin d’exactitude dans le micropaiement (nanopaiement?!).

Moi aussi, je préfère DECIMAL aux types d'argent spécifiques aux SGBD, vous êtes plus sûr en conservant ce type de logique dans l'application OMI. Une autre approche dans le même sens consiste simplement à utiliser un entier [long], avec un formatage en ¤unit.subunit pour la lisibilité humaine (¤ = symbole monétaire) effectué au niveau de l'application.

Le type de données money sur SQL Server comporte quatre chiffres après le signe décimal.

Dans la documentation en ligne de SQL Server 2000:

Les données monétaires représentent des montants monétaires positifs ou négatifs. Dans Microsoft & # 174; SQL Server & # 8482; 2000, les données monétaires sont stockées en utilisant les 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 -214748,3648 et 214,748.3647 (nécessite 4 octets pour stocker une valeur). Si un nombre supérieur de décimales est requis, utilisez plutôt le type de données décimal.

Vous devrez parfois atteindre moins d’un centime et certaines monnaies internationales utilisent des démoniations très volumineuses. Par exemple, vous pourriez facturer à vos clients 0,088 centimes par transaction. Dans ma base de données Oracle, les colonnes sont définies comme NUMBER (20,4)

Si vous envisagez de faire des opérations arithmétiques dans la base de données (en multipliant les taux de facturation, etc.), vous voudrez probablement beaucoup plus de précision que ne le suggèrent les gens ici, pour les mêmes raisons que vous. 'ne souhaite jamais utiliser moins qu'une valeur à virgule flottante double précision dans le code de l'application.

Si vous utilisiez IBM Informix Dynamic Server, vous auriez un type MONEY qui serait 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, selon ce que vous devez stocker, vous pouvez utiliser DECIMAL (16,2) - suffisamment grand pour contenir le déficit fédéral américain, au cent près - ou vous pouvez utiliser une plage plus petite ou des décimales plus nombreuses.

Je pense que vos exigences ou celles de vos clients devraient en grande partie dicter la précision et l’échelle à utiliser. Par exemple, pour le site Web de commerce électronique sur lequel je travaille et traite uniquement de l'argent en GBP, il m'a été demandé de le conserver en décimal (6, 2).

Une réponse tardive ici, mais j'ai déjà utilisé

DECIMAL(13,2)

qui, j’ai raison, devrait permettre jusqu’à 99 999 999 999,99.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top