Какой тип поля SQL Server лучше всего подходит для хранения значений цен? - PullRequest
27 голосов
/ 03 июня 2010

Мне интересно, какой тип цены лучше использовать в SQL Server для структуры магазина?

Глядя на этот обзор у нас есть типы данных, называемые money , smallmoney , тогда у нас есть десятичное / числовое и, наконец, float и real .

Имя, память / использование диска и диапазоны значений:

  • Деньги: 8 байтов (значения: от -922 337 203 685 477,5808 до + 922 337 203 685 477,5807)
  • Smallmoney: 4 байта (значения: от -214 748,3648 до + 214 748,3647)
  • Десятичное число: 9 [по умолчанию, мин. 5] байтов (значения: от -10 ^ 38 +1 до 10 ^ 38 -1)
  • Число с плавающей запятой: 8 байтов (значения: -1,79E + 308 до 1,79E + 308)
  • Реальный: 4 байта (значения: от -3,40E + 38 до 3,40E + 38)

Действительно ли целесообразно хранить значения цен в этих типах? Как насчет, например. INT

  • Int: 4 байта (значения: от -2 147 483 648 до 2 147 483 647)

Допустим, в магазине используются доллары, у них есть центы, но я не вижу, чтобы цены составляли 49,2142342 доллара, поэтому использование большого количества десятичных знаков, показывающих центы, кажется пустой тратой пропускной способности SQL. Во-вторых, большинство магазинов не показывали бы цены около 200.000.000 (по крайней мере, не в обычных интернет-магазинах, если кто-то не пытается продать мне знаменитую башню в Париже)

Так почему бы не пойти на Int?

Int - это быстрое, его всего 4 байта, и вы можете легко делать десятичные дроби, сохраняя значения в центах вместо долларов, а затем делить их при представлении значений.

Другой подход заключается в использовании smallmoney, который также составляет 4 байта, но для этого потребуется вычисление математической части ЦП, где Int - целочисленная мощность ... с другой стороны, вам нужно разделить каждое одиночный исход.

При использовании полей smallmoney / money возникают ли проблемы с валютой в региональных настройках? что они тоже перенесут в C # / .NET?

Есть плюсы / минусы? Перейти на целые цены или мелкие деньги или что-то другое?

Что говорит ваш опыт?

Ответы [ 7 ]

21 голосов
/ 03 июня 2010

Если вы абсолютно уверены, что ваши номера всегда будут находиться в диапазоне smallmoney, используйте это, и вы сможете сэкономить несколько байтов.В противном случае я бы использовал money.Но помните, в наши дни хранение дешево.Дополнительные 4 байта над 100 миллионами записей по-прежнему меньше половины ГБ.Однако, как указывает @marc_s, использование smallmoney, если вы можете, уменьшит объем памяти, занимаемой SQL-сервером.

Короче говоря, если вы можете избежать использования smallmoney, сделайте.Если вы думаете, что может превысить максимум, используйте money.

Но, если не , используйте тип с плавающей запятой или вы получите проблемы с округлением иначнет терять или получать случайные центы, если только вы не справитесь с ними должным образом.

Мой аргумент против использования int: зачем изобретать велосипед, сохраняя int, а затем не забывая делить на 100 (10000), чтобы получить значение и умножить обратно, когда вы собираетесь сохранить значение.Насколько я понимаю, типы денег используют int или long в качестве базового типа хранилища в любом случае.

Что касается соответствующего типа данных в .NET, это будет decimal (что также позволит избежатьвопросы округления в вашем коде C #).

9 голосов
/ 03 июня 2010

Используйте тип данных Деньги , если вы храните деньги (если не моделируете огромные суммы денег, например государственный долг) - это позволяет избежать проблем с точностью / округлением.

Множество преимуществ денег… Тип данных!

7 голосов
/ 03 июня 2010

ИСПОЛЬЗОВАТЬ ЧИСЛЕННОЕ / ДЕЦИМАЛЬНОЕ. Избегайте ДЕНЬГИ / МАЛЕНЬКИЕ ДЕНЬГИ. Вот пример того, почему . Рано или поздно типы MONEY / SMALLMONEY, скорее всего, подведут вас из-за ошибок округления. Типы денег полностью избыточны и не приносят ничего полезного - сумма в валюте является просто другим десятичным числом, как и любое другое.

Наконец, типы MONEY / SMALLMONEY являются собственностью Microsoft. NUMERIC / DECIMAL являются частью стандарта SQL. Они используются, распознаются и понимаются большим количеством людей и поддерживаются большинством СУБД и другого программного обеспечения.

4 голосов
/ 03 июня 2010

Лично я бы использовал мелкие деньги или деньги для хранения цен магазина.

Использование int добавляет сложности в другом месте.

И 200 миллионов - это абсолютно действительная цена в корейских вонах или в индонезийских рупиях ...

3 голосов
/ 03 июня 2010

Типы данных SQL money и smallmoney разрешаются в тип c # decimal:

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

Так что я думаю, что вы могли бы также пойти на decimal. Лично я использовал double всю свою жизнь, работая в финансовой отрасли, и у меня не было проблем с производительностью и т. Д. На самом деле, я обнаружил, что для определенных расчетов и т. Д. Наличие большего типа данных позволяет получить более высокую степень точности.

1 голос
/ 03 июня 2010

Я бы выбрал тип данных Деньги. По отдельности вы не можете превышать значение в Smallmoney, но для нескольких предметов будет легко его превысить.

0 голосов
/ 17 июня 2010

В моем приложении для ломбардов операторы ломбардов предоставляют кредиты от 5 до 10 000 долларов США. Когда они вычисляют сумму кредита, они округляют ее до ближайшего доллара, чтобы избегать работы с центами (то же самое относится и к выплате процентов). Когда сумма кредита превышает 50,00 долларов США, они округляют ее до ближайших 5,00 долларов США (то есть 50 долларов США, 55 долларов США, 60 долларов США ...) снова, чтобы минимизировать исчерпание долларовых купюр. Поэтому я использую DECIMAL (7,2) для транзакции.calculated_loan_amount и DECIMAL (5,0) для транзакции.loan_amount. Приложение рассчитывает сумму кредита до копейки и помещает эту сумму в loan_amount, где оно округляется до ближайшего доллара, когда он ниже 50 долларов, или до ближайших 5 долларов, если больше.

...