web-dev-qa-db-fra.com

Quel type de champ SQL Server convient le mieux pour stocker des valeurs de prix?

Je me demande quel est le meilleur type pour un champ de prix dans SQL Server pour une structure de type boutique?

En regardant cet aperçu nous avons des types de données appelés money , smallmoney , alors nous avons décimal/numérique et enfin float et real .

Nom, utilisation de la mémoire/du disque et plages de valeurs:

  • Money: 8 octets (valeurs: -922,337,203,685,477,5808 à +922,337,203,685,477,5807)
  • Smallmoney: 4 octets (valeurs: -214,748,3648 à +214 748,3647)
  • Décimal: 9 [défaut, min. 5] octets (valeurs: -10 ^ 38 +1 à 10 ^ 38 -1)
  • Float: 8 octets (valeurs: -1.79E + 308 à 1.79E + 308)
  • Real: 4 octets (valeurs: -3.40E + 38 à 3.40E + 38)

Est-il vraiment sage de stocker des valeurs de prix dans ces types? Qu'en est-il par exemple. INT?

  • Int: 4 octets (valeurs: -2 147 483 648 à 2 147 483 647)

Disons qu'un magasin utilise des dollars, il a des cents, mais je ne vois pas les prix se chiffrer à 49,2142342 $, alors utiliser beaucoup de décimales montrant des cents semble un gaspillage de bande passante SQL. Deuxièmement, la plupart des magasins n’indiqueraient pas de prix proches de 200 000 000 (pas du moins dans les boutiques en ligne normales, à moins que quelqu'un essaie de me vendre une célèbre tour à Paris).

Alors pourquoi ne pas aller pour un int?

Un int est rapide, ce ne sont que 4 octets et vous pouvez facilement créer des décimales, en sauvegardant les valeurs en cents au lieu de dollars et en les divisant ensuite lorsque vous présentez les valeurs.

L'autre approche consisterait à utiliser smallmoney, qui est également de 4 octets, mais cela nécessitera que la partie mathématique de la CPU effectue le calcul, où Int étant une puissance entière ... en revanche, vous devrez diviser chaque résultat.

Existe-t-il des problèmes liés à la "devise" avec les paramètres régionaux lors de l'utilisation de champs SmallMoney/Money? qu'est-ce que ces transferts vont aussi en C #/.NET?

Des avantages/inconvénients? Optez pour des prix entiers ou smallmoney ou un autre?

Que dit votre expérience?

26
BerggreenDK

Si vous êtes absolument certain que vos numéros resteront toujours dans la plage de smallmoney, utilisez-le et vous pourrez économiser quelques octets. Sinon, j'utiliserais money. Mais rappelez-vous, le stockage est bon marché ces jours-ci. Les 4 octets supplémentaires sur 100 millions d'enregistrements représentent toujours moins d'un demi-Go. Comme @marc_s le fait remarquer, cependant, utiliser smallmoney si vous le pouvez permet de réduire l'encombrement de la mémoire du serveur SQL.

Longue histoire courte, si vous pouvez vous en tirer avec smallmoney, faites-le. Si vous pensez que pourriez dépasser le maximum, utilisez money.

Cependant, utilisez pas un type décimal flottant, sinon vous aurez des problèmes d'arrondi et vous perdrez ou gagnerez des centimes au hasard, à moins que vous ne les traitiez correctement.

Mon argument contre l'utilisation de int: Pourquoi réinventer la roue en stockant une int et en ayant ensuite à se souvenir de diviser par 100 (10000) pour récupérer la valeur et à multiplier en arrière lorsque vous allez stocker la valeur. D'après ce que je comprends, les types d'argent utilisent quand même int ou long comme type de stockage sous-jacent.

En ce qui concerne le type de données correspondant dans .NET, ce sera decimal (ce qui évitera également les problèmes d'arrondi dans votre code C #).

20
lc.

Utilisez le type de données Money si vous stockez de l'argent (sauf si vous modélisez des sommes énormes comme la dette nationale) - cela évite les problèmes de précision/d'arrondi.

Les nombreux avantages de l'argent… Type de données!

9
Mitch Wheat

UTILISEZ NUMÉRIQUE/DÉCIMAL. Évitez l'ARGENT/SMALLMONEY. Voici un exemple de pourquoi . Tôt ou tard, les types MONEY/SMALLMONEY vous laisseront probablement tomber à cause d'erreurs d'arrondi. Les types d’argent sont complètement redondants et n’apportent rien d’utile - un montant en devise n’est qu’un nombre décimal comme un autre.

Enfin, les types MONEY/SMALLMONEY sont la propriété de Microsoft. NUMERIC/DECIMAL font partie du standard SQL. Ils sont utilisés, reconnus et compris par plus de personnes et sont pris en charge par la plupart des SGBD et autres logiciels.

7
nvogel

Personnellement, j'utiliserais smallmoney ou money pour stocker les prix des magasins.

Utiliser int ajoute de la complexité ailleurs.

Et 200 millions est un prix parfaitement valable en won coréen ou en roupies indonésiennes aussi ...

4
gbn

Les types de données SQL money et smallmoney sont tous deux résolus en type c # decimal:

http://msdn.Microsoft.com/en-us/library/system.data.sqltypes.sqlmoney(v=VS.71).aspx

Je pense donc que vous pourriez aussi bien choisir decimal. Personnellement, j'ai utilisé double toute ma vie dans le secteur financier et je n'ai pas rencontré de problèmes de performances, etc. En fait, j'ai constaté que pour certains calculs, etc., le fait d'avoir un type de données plus grand permet un degré de précision supérieur. .

3
code4life

Je choisirais le type de données Money. Invididuellement, vous ne pouvez pas dépasser la valeur de Smallmoney, mais il serait facile pour plusieurs objets de la dépasser.

1
Craig T

Dans mon application de prêteur sur gages, les exploitants de prêteurs sur gages prêtent de 5,00 $ à 10 000,00 Lorsqu'ils calculent le montant du prêt, ils l'entourent au dollar près afin d'éviter De traiter avec des cents (il en va de même pour les paiements d'intérêts ). Lorsque le montant du prêt est supérieur à 50,00 $, il sera arrondi au 5,00 $ près (50 $, 55 $, 60 $, etc.), ce qui minimisera également le manque de billets en dollars. Par conséquent, j'utilise DECIMAL (7,2) pour transaction.calculated_loan_amount et DECIMAL (5,0) pour transaction.loan_amount. L'application calcule le montant du prêt en centimes et place ce montant sur loan_amount où il est arrondi. au dollar près quand moins de 50 $ ou à 5 $ quand plus grand. 

0
Frank R.