Quel type de champ SQL Server est le meilleur pour stocker les 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?

Regardant cette vue d'ensemble, nous avons des types de données appelé argent, smallmoney, puis nous avons décimal/numérique et enfin float et réel.

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

  • Argent: {[6] } 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 [par défaut, min. 5] octets (valeurs: -10^38 +1 à 10^38 -1 )
  • Float: 8 octets (valeurs: -1.79 E+308 à 1,79 E+308 )
  • Réel: 4 octets (valeurs: -3.40 E+38 à 3,40 E+38 )

Est - il vraiment sage de stocker les valeurs de prix dans ces types? Que penser, par exemple. INT?

  • Int: {[6] } 4 octets (valeurs: -2 147 483 648 à 2 147 483 647)

Disons un magasin utilise des dollars, ils ont des cents, mais je ne vois pas les prix étant $49.2142342 donc l'utilisation de beaucoup de décimales montrant des cents semble un gaspillage de bande passante SQL. Deuxièmement, la plupart des magasins ne montreraient pas de prix près de 200.000.000 (pas dans les boutiques en ligne normales au moins, à moins que quelqu'un essaie de me vendre une célèbre tour à Paris)

Alors, pourquoi ne pas opter pour un int?

Un int est rapide, ses seulement 4 octets et vous pouvez facilement faire des décimales, en enregistrant des valeurs en cents au lieu de dollars, puis diviser quand vous présenter les valeurs.

L'autre approche serait d'utiliser smallmoney qui est aussi de 4 octets, mais cela nécessitera la partie mathématique du CPU pour faire le calc, où as Int est une puissance entière... à la baisse, vous devrez diviser chaque résultat.

Y a-t-il des problèmes liés à la "monnaie" avec les paramètres régionaux lors de l'utilisation des champs smallmoney/money? que vont-ils transférer aussi en C#/. NET ?

Des avantages/inconvénients? Optez pour des prix entiers ou smallmoney ou certains les autres?

Que dit votre expérience?

25
demandé sur halfer 2010-06-03 07:20:20

7 réponses

Si vous êtes absolument sûr que vos nombres resteront toujours dans la plage de smallmoney, utilisez-le et vous pouvez enregistrer 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 sont toujours inférieurs à la moitié D'un go. Comme le souligne @marc_s, cependant, l'utilisation de smallmoney si vous le pouvez réduira l'empreinte mémoire de SQL server.

Longue histoire courte, si vous pouvez vous en sortir avec smallmoney, faire. Si vous pensez que vous peut aller sur le max, utilisez money.

Mais, n'utilisez pas un type décimal flottant ou vous obtiendrez des problèmes d'arrondi et commencerez à perdre ou à gagner des cents aléatoires, à moins que vous ne les traitiez correctement.

Mon argument contre l'utilisation de int: pourquoi réinventer la roue en stockant un int et ensuite devoir se rappeler de diviser par 100 (10000) pour récupérer la valeur et multiplier quand vous allez stocker la valeur. Ma compréhension est que les types d'argent utilisent un int ou long comme sous-jacent type de stockage de toute façon.

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
répondu lc. 2010-06-03 06:46:18

Utilisez le type de données Money Si vous stockez de l'argent (à moins de modéliser d'énormes quantités d'argent comme la dette nationale) - cela évite les problèmes de précision/arrondi.

Les nombreux avantages de L'Argent...Type de données!

9
répondu Mitch Wheat 2010-06-03 03:26:07

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 en raison d'erreurs d'arrondi. Les types d'argent sont complètement redondants et n'atteignent rien d'utile-un montant en monnaie étant juste un autre nombre décimal comme un autre.

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

7
répondu sqlvogel 2010-06-03 05:46:17

Personnellement, j'utiliserais smallmoney ou de l'argent pour stocker les prix des magasins.

L'utilisation de 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
répondu gbn 2010-06-03 03:28:37

Les types de données SQL money et smallmoney résolvent tous les deux en C# decimal type:

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

Donc, je pense que vous pourriez aussi bien aller pour decimal. Personnellement, j'ai utilisé double toute ma vie dans le secteur financier et je n'ai pas connu de problèmes de performance, etc. En fait, j'ai trouvé cela pour certains calculs, etc., ayant un plus grand type de données permet pour plus haut degré de précision.

3
répondu code4life 2010-06-03 03:31:22

J'irais pour le type de données Money. Invididually vous ne pouvez pas dépasser la valeur dans Smallmoney, mais il serait facile pour plusieurs éléments de le dépasser.

1
répondu Craig T 2010-06-03 03:31:36

Dans mon app prêteur sur gages, les opérateurs de prêteur sur gages prêtent de $ 5.00 à $ 10,000. 00 Quand ils calculent le montant du prêt ils l'arrondissent AU dollar le plus proche afin de évitez 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 ils arrondiront à la plus proche $5.00 (c.-à-d. $ 50, $ 55, $ 60 ...), encore une fois pour minimiser l'épuisement des billets d'un dollar. Par conséquent, j'utilise DECIMAL(7,2) pour la transaction.calculated_loan_amount et décimal (5,0) pour transaction.loan_amount. L'application calcule le montant du prêt au penny et place ce montant dans loan_amount où il est arrondi au dollar le plus proche lorsque inférieur à 50 $ou au plus proche 5,00 $lorsque plus.

0
répondu Frank R. 2010-06-17 06:05:24