Le stockage de l'argent dans une colonne decimal - ce que la précision et l'échelle?
Je suis en utilisant une colonne decimal pour stocker les valeurs de la monnaie sur une base de données, et aujourd'hui, je me demandais ce que la précision et l'échelle à utiliser.
Depuis la soi-disant char colonnes de largeur fixe sont plus efficaces, je pensais la même chose pourrait être vraie pour les colonnes decimal. S'agit-il?
Et quelle précision et l'échelle dois-je utiliser? Je pensais précision 24/8. C'est que overkill, ou pas assez ok?
C'est ce que j'ai décidé de faire:
- Stocker le taux de conversion (le cas échéant) dans la table des transactions en lui-même, comme un float
- Magasin de la monnaie dans la table compte
- Le montant de la transaction sera un
DECIMAL(19,4)
- Tous les calculs à l'aide d'un taux de conversion seront traitées par mon application j'ai donc garder le contrôle de l'arrondi
Je ne pense pas qu'un flotteur pour le taux de conversion est un problème, puisque c'est surtout pour la référence, et je vais être un moulage d'une virgule, de toute façon.
Merci à vous tous pour votre précieuse contribution.
- Posez-vous la question: Est-il vraiment nécessaire de stocker les données sous forme décimale? Ne puis-je pas stocker les données en Cents/Pennies -> entiers ?
DECIMAL(19, 4)
est un choix populaire case this vérifiez également ici Monnaie Mondiale Formats de décider du nombre de décimales à utiliser , l'espérance aide.
Vous devez vous connecter pour publier un commentaire.
Si vous cherchez un one-size-fits-all, je vous suggère de
DECIMAL(19, 4)
est un choix populaire (un rapide Google en témoigne). Je pense que cela provient de l'ancien VBA/Access/Jet type de données monétaire, étant le premier point fixe de type décimal dans la langue;Decimal
n'est entré dans la version 1.0' style (c'est à dire pas entièrement mis en œuvre) en VB6/VBA6/Jet 4.0.La règle de base pour de stockage de point fixe des valeurs décimales est pour stocker au moins une décimale après la virgule que vous avez réellement besoin pour permettre l'arrondissement. L'une des raisons pour la cartographie de la vieille
Currency
type dans le front-end àDECIMAL(19, 4)
type dans le dos fin, c'est queCurrency
exposé des banquiers arrondi par la nature, tandis queDECIMAL(p, s)
arrondi par troncature.Un supplément de décimale dans le stockage pour
DECIMAL
permet une coutume algorithme arrondi à être mis en œuvre plutôt que de prendre le fournisseur par défaut (et des banquiers arrondissement est alarmant, pour dire le moins, pour un concepteur attend à ce que tous les valeurs se terminant par, 5 à la ronde à l'écart à partir de zéro).Oui,
DECIMAL(24, 8)
sonne comme exagéré pour moi. La plupart des devises sont cotées à quatre ou cinq décimales. Je sais de situations où une échelle décimale de 8 (ou plus) est nécessaire, mais c'est là un "normal" montant monétaire (par exemple quatre décimales) a été pro rata d, ce qui implique la précision décimale doit être réduite en conséquence (également tenir compte d'un type à virgule flottante dans de telles circonstances). Et on n'a pas beaucoup d'argent aujourd'hui pour exiger une précision décimale de 24 🙂Cependant, plutôt que de one-size-fits-all approche, certaines recherches peuvent être dans l'ordre. Demandez à votre concepteur ou de l'expert du domaine sur les règles comptables qui peuvent être applicables: les PCGR, UE, etc. J'ai vaguement rappeler certains pays de l'UE intra-des transferts de l'état avec des règles explicites pour l'arrondi à cinq décimales, donc à l'aide de
DECIMAL(p, 6)
pour le stockage. Comptables généralement semblent favorables à quatre décimales.PS Éviter de SQL Server
MONEY
type de données, car il a de sérieux problèmes avec la précision lors de l'arrondissement, parmi d'autres considérations, telles que la portabilité etc. Voir Aaron Bertrand blog.De Microsoft et de la langue concepteurs ont choisi l'arrondi parce que les concepteurs de matériel choisi [citation?]. Il est consacré par l'Institute of Electrical and Electronics Engineers (IEEE), par exemple les normes. Et les concepteurs de matériel choisi parce que les mathématiciens préfèrent. Voir Wikipédia; pour paraphraser: 1906 édition des Probabilités et Théorie des Erreurs appelé ce "le de l'ordinateur règle" ("ordinateurs" en ce sens, les humains qui effectuer des calculs).
DECIMAL(19, 4)
plus populaire queDECIMAL(19, 2)
? La plupart des devises du monde entier ne sont que deux décimales.Nous avons récemment mis en place un système qui doit gérer des valeurs dans de multiples devises et convertir entre eux, et a trouvé quelques choses à la dure.
NE JAMAIS UTILISER DES NOMBRES À VIRGULE FLOTTANTE DE L'ARGENT
Arithmétique à virgule flottante introduit des inexactitudes qui peuvent ne pas être remarqué jusqu'à ce qu'ils ont vissé quelque chose. Toutes les valeurs doivent être stockés comme des entiers ou des décimaux types, et si vous choisissez d'utiliser un corrigé-type décimal puis assurez-vous que vous comprenez exactement ce que ce type n'sous le capot (c'est à dire, ne l'interne, l'utilisation d'un nombre entier ou à virgule flottante type).
Lorsque vous avez besoin de faire des calculs ou des conversions:
Lors de la conversion d'un nombre à virgule flottante à un nombre entier dans l'étape 3, ne pas les jeter elle - utiliser une fonction mathématique pour le tour en premier. Ce sera généralement
round
, bien que dans des cas particuliers, il pourrait êtrefloor
ouceil
. Connaître la différence et choisir avec soin.Stocker le type d'un nombre à côté de la valeur
Cela peut ne pas être aussi important pour vous si vous êtes seulement de la manipulation de monnaie, mais il était important pour nous dans le traitement des devises multiples. Nous avons utilisé les 3 caractères de code pour une devise, comme l'USD, GBP, JPY, EUR, etc.
Selon la situation, il peut également être utile pour stocker:
Connaître la précision des limites des nombres que vous avez à traiter avec des
Pour de vrai valeurs, vous voulez être précis comme la plus petite unité de la devise. Cela signifie que vous n'avez pas de valeurs plus petites que un centime, un centime, un yen, d'un marais, etc. Ne pas stocker des valeurs avec une précision plus élevée que celle pour aucune raison.
En interne, vous pouvez choisir de traiter avec des petites valeurs, auquel cas c'est un différents type de la valeur de la monnaie. Assurez-vous que votre code ne sait qui est qui et ne pas les mélanger. Évitez d'utiliser des valeurs à virgule flottante, même ici.
D'ajouter toutes ces règles, nous avons adopté les règles suivantes. Dans le code en cours d'exécution, les monnaies sont stockées à l'aide d'un entier dans la plus petite unité.
Dans la base de données, les valeurs sont stockées en tant que chaîne de caractères dans le format suivant:
Qui stocke la valeur de $25.00. Nous avons été en mesure de le faire seulement parce que le code qui traite des monnaies n'a pas besoin d'être à l'intérieur de la couche de base de données elle-même, de sorte que toutes les valeurs peuvent être converties en mémoire. D'autres situations sera sans aucun doute se prêtent à d'autres solutions.
Et dans le cas où je n'ai pas précisé plus haut, ne pas utiliser float!
bigint
si vous avez l'intention sur le tri par la quantité. Et ne perdez pas votre temps avec PHP 32 bits lorsque vous traitez avec de grands entiers, la mise à niveau vers la version 64bit ou Node.JS 😉Lors de la manipulation de l'argent dans MySQL, DÉCIMAL(13,2) si vous connaissez la précision de votre argent, des valeurs ou utiliser le DOUBLE si vous voulez juste un rapide "suffisamment bonne" valeur approximative.
Donc, si votre application a besoin de gérer l'argent, des valeurs jusqu'à un billion de dollars (ou d'euros ou de livres), alors cela devrait fonctionner:
Ou, si vous avez besoin pour se conformer à la Les PCGR alors utiliser:
4 décimales serait vous donner la précision de stocker le plus petit du monde de la devise sous-unités. Vous pouvez le prendre vers le bas si vous avez besoin de micropaiement (nanopayment?!) la précision.
Moi aussi, je préfère
DECIMAL
à SGBD spécifique de l'argent, vous êtes sûr de garder ce genre de logique dans l'application de l'OMI. Une autre approche dans le même sens est tout simplement à utiliser un [long] entier, avec la mise en forme dans ¤l'unité.sous-unité à des fins de lisibilité (¤ = symbole de la monnaie) se fait au niveau de l'application.L'argent de type de données sur SQL Server dispose de quatre chiffres après la virgule.
À partir de SQL Server 2000 Livres en Ligne:
Monétaire de données représente des montants positifs ou négatifs de l'argent. Dans Microsoft® SQL Server™ 2000, monétaire, les données sont stockées à l'aide de l'argent et smallmoney types de données. Monétaire, les données peuvent être stockées pour une précision de quatre décimales. L'utilisation de l'argent de type de données pour stocker des valeurs dans la plage de -922,337,203,685,477.5808 à +922,337,203,685,477.5807 (nécessite 8 octets pour stocker une valeur). Utiliser le smallmoney type de données à stocker des valeurs dans la plage de -214,748.3648 par 214,748.3647 (nécessite 4 octets pour stocker une valeur). Si un plus grand nombre de décimales sont nécessaires, utilisez le type de données décimal au lieu.
Parfois, vous aurez besoin d'aller à moins d'un cent et il y a des monnaies internationales qui utilisent un très grand demoniations. Par exemple, vous pouvez facturer vos clients 0.088 cents par transaction. Dans ma base de données Oracle les colonnes sont définies comme NOMBRE(20,4)
Si vous allez faire toute sorte d'opérations arithmétiques dans la DB (en multipliant hors des taux de facturation et ainsi de suite), vous voudrez probablement beaucoup plus de précision que les gens d'ici sont ce qui suggère, pour les mêmes raisons que vous n'auriez jamais souhaitez utiliser rien de moins que d'une virgule flottante en double précision de la valeur dans le code de l'application.
BigDecimal
), mais pour un long moment, il était en double précision (pensezdouble
au lieu defloat
). Aussi, la précision arbitraire considérablement les performances des sanctions dans certains cas. Le test est certainement la bonne approche.Si vous utilisez IBM Informix Dynamic Server, vous avez un type monétaire qui est une variante mineure sur la DÉCIMALE ou de type NUMÉRIQUE. C'est toujours un point fixe de type (alors que DÉCIMAL peut être d'un type à virgule flottante). Vous pouvez spécifier une échelle de 1 à 32, et une précision de 0 à 32 (défaut à une échelle de 16 et une précision de 2). Ainsi, en fonction de ce que vous avez besoin de magasin, vous pourriez utiliser la VIRGULE(16,2) - encore assez grande pour contenir le Déficit AMÉRICAIN, au cent le plus proche - ou vous pouvez utiliser une plage plus petite, ou plus de décimales.
Je pense que pour une grande partie de votre ou vos exigences du client doit dicter ce que la précision et l'échelle à utiliser. Par exemple, pour le site d'e-commerce, je suis en train de travailler sur qui traite de l'argent en livres sterling seulement, j'ai été obligé de le garder à la Décimale( 6, 2 ).
Un retard de réponse ici, mais j'ai utilisé
qui je suis en droit de penser doit permettre jusqu'à 99,999,999,999.99.