Хранение денег в десятичном столбце - что точность и масштаб?

165
задан Nick Chammas 19 January 2012 в 01:59
поделиться

8 ответов

Если бы Вы ищете единое, я предложил бы DECIMAL(19, 4), популярный выбор (быстрый Google подтверждает это). Я думаю, что это происходит из старого VBA/Access/Jet типа данных Валюты, будучи первым типом десятичного числа фиксированной точки на языке; Decimal только прибыл в стиль 'версии 1.0' (т.е. не полностью реализованный) в VB6/VBA6/Jet 4.0.

эмпирическое правило для [1 112] устройство хранения данных из десятичных значений фиксированной точки должно сохранить, по крайней мере, еще один десятичный разряд, чем Вы на самом деле требуете для обеспечения округления. Одна из причин отображения старого Currency тип во фронтэнде к DECIMAL(19, 4) тип в бэкэнде была то, что Currency округление показанных банкиров по своей природе, тогда как DECIMAL(p, s) округлена усечением.

дополнительный десятичный разряд в устройстве хранения данных для DECIMAL позволяет пользовательскому алгоритму округления быть реализованным вместо того, чтобы брать значение по умолчанию поставщика (и округление банкиров вызывает тревогу, по меньшей мере, для разработчика, ожидающего все значения, заканчивающиеся в.5 к раунду далеко от нуля).

Да, DECIMAL(24, 8) походит на излишество мне. Большинство валют заключается в кавычки к четырем или пяти десятичным разрядам. Я знаю о ситуациях, где десятичная система счисления 8 (или больше) требуется, но это - то, где 'нормальная' денежная сумма (говорят четыре десятичных разряда) была про rata'd, подразумевая, что десятичная точность должна быть уменьшена соответственно (также рассматривают тип с плавающей точкой при таких обстоятельствах). И ни у кого нет так большого количества денег в наше время для требования десятичной точности 24:)

Однако, а не единый подход, некоторое исследование может быть в порядке. Спросите своего разработчика или специалиста по проблемной области о правилах бухгалтерского учета, которые могут быть применимыми: GAAP, ЕС, и т.д. Я неопределенно вспоминаю некоторый ЕС внутриштатные передачи с явными правилами для округления к пяти десятичным разрядам, поэтому с помощью DECIMAL(p, 6) для устройства хранения данных. Бухгалтеры обычно, кажется, одобряют четыре десятичных разряда.

<час>

пз Избегают SQL Server MONEY тип данных, потому что это имеет серьезные проблемы с точностью, когда округление, среди других соображений, таких как мобильность и т.д. Видит блог .

Aaron Bertrand <час>

, Microsoft и разработчики языка выбрали округление банкира, потому что аппаратные разработчики выбрали его [цитата?]. Это хранится в Институте инженеров электротехники и электроники (IEEE) стандарты, например. И аппаратные разработчики выбрали его, потому что математики предпочитают его. См. Википедия ; перефразировать: выпуск 1906 года Вероятности и Теория Ошибок назвали это 'правилом компьютера' ("компьютеры", означающие людей, которые выполняют вычисления).

165
ответ дан TacoV 23 November 2019 в 21:09
поделиться

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

НИКОГДА ЧИСЛА С ПЛАВАЮЩЕЙ ТОЧКОЙ ИСПОЛЬЗОВАНИЯ ЗА ДЕНЬГИ

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

, Когда действительно необходимо сделать вычисления или преобразования:

  1. Преобразовывают значения в плавающую точку
  2. , Вычисляют новое значение
  3. Раунд число и преобразовывают его назад в целое число

При преобразовании числа с плавающей точкой назад в целое число на шаге 3, только бросьте, это - использует математическую функцию для раунда это сначала. Это обычно будет round, хотя в особых случаях это могло быть floor или ceil. Знайте различие и выберите тщательно.

Хранилище тип числа вместе со значением

Это не может быть столь же важно для Вас, если Вы только обрабатываете одну валюту, но это было важно для нас в обработке нескольких валют. Мы использовали 3 кода символа за валюту, такую как доллар США, фунт стерлингов, JPY, евро, и т.д.

В зависимости от ситуации, может также быть полезно сохранить:

  • , Является ли число прежде или после уплаты налога (и чем была налоговая ставка)
  • , Ли число является результатом преобразования (и из чего это было преобразовано)

Знают границы точности чисел, Вы имеете дело с [1 129]

Для действительных значений, Вы хотите быть столь же точными как самая маленькая единица валюты. Это означает, что у Вас нет значений, меньших, чем цент, пенс, иена, болото, и т.д. не снабжает значения более высокой точностью, чем это ни по какой причине.

Внутренне, можно принять решение иметь дело с меньшими значениями, в этом случае это другой тип значения валюты . Удостоверьтесь, что Ваш код знает, который является, который и не перепутали их. Избегайте использования значений с плавающей точкой даже здесь.

<час>

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

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

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

В базе данных, значения хранятся как строка в следующем формате:

USD:2500

, Который хранит значение 25,00$. Мы смогли сделать это только потому, что код, который имеет дело с валютами, не должен быть на самом слое базы данных, таким образом, все значения могут быть преобразованы в память сначала. Другие ситуации несомненно предоставят себя другим решениям.

<час>

И в случае, если я не прояснил ранее, , не используют плавание!

97
ответ дан Marcus Downing 23 November 2019 в 21:09
поделиться

4 десятичных разряда дали бы Вам точность для хранения самых маленьких субблоков валюты в мире. Можно ли удалить его далее при необходимости в микрооплате (нанооплата?!) точность.

я также предпочитаю DECIMAL определенным для DBMS денежным типам, Вы - более безопасное хранение такой логики в приложении IMO. Другой подход в том же направлении должен просто использовать [длинное] целое число с форматированием в В¤unit.subunit для удобства чтения (В¤ = обозначение денежной единицы) сделанный на прикладном уровне.

2
ответ дан Mark Stewart 23 November 2019 в 21:09
поделиться

Тип данных money на SQL Server имеет четыре цифры после десятичного числа.

Из Книг SQL Server 2000 Онлайн:

Денежные данные представляют положительные или отрицательные суммы денег. В MicrosoftВ® SQL Serverв „ў 2000, денежные данные хранятся с помощью типов данных money и типов данных smallmoney. Денежные данные могут храниться с точностью до четырех десятичных разрядов. Используйте тип данных money для хранения значений в диапазоне от-922,337,203,685,477.5808 до +922,337,203,685,477.5807 (требует, чтобы 8 байтов сохранили значение). Используйте тип данных smallmoney для хранения значений в диапазоне от-214,748.3648 до 214,748.3647 (требует, чтобы 4 байта сохранили значение). Если большее количество десятичных разрядов требуется, используйте тип данных decimal вместо этого.

1
ответ дан Austin Salonen 23 November 2019 в 21:09
поделиться

Иногда необходимо будет перейти меньше чем к центу и существуют международные валюты, которые используют очень большой demoniations. Например, Вы могли бы заряжать своих клиентов 0,088 центов за транзакцию. В моей базе данных Oracle столбцы определяются как НОМЕР (20,4)

1
ответ дан WW. 23 November 2019 в 21:09
поделиться

Если Вы будете собираться быть выполнением какого-либо вида арифметических операций в DB (умножающий расценки и так далее), Вы, вероятно, захотите намного больше точности, чем люди здесь предлагают по тем же причинам, что Вы никогда не хотели бы использовать что-то меньшее чем значение с плавающей точкой двойной точности в коде приложения.

1
ответ дан Hank Gay 23 November 2019 в 21:09
поделиться

При использовании IBM Informix Динамический Сервер у Вас был бы ДЕНЕЖНЫЙ тип, который является незначительным вариантом на ДЕСЯТИЧНОМ или ЧИСЛОВОМ типе. Это всегда - тип фиксированной точки (тогда как ДЕСЯТИЧНОЕ ЧИСЛО может быть типом с плавающей точкой). Можно определить масштаб от 1 до 32 и точность от 0 до 32 (принимающий значение по умолчанию к масштабу 16 и точности 2). Так, в зависимости от того, что необходимо сохранить, Вы могли бы использовать ДЕСЯТИЧНОЕ ЧИСЛО (16,2) - все еще достаточно большой для содержания американского федерального Дефицита к самому близкому центу - или Вы могли бы использовать меньший диапазон или больше десятичных разрядов.

0
ответ дан Jonathan Leffler 23 November 2019 в 21:09
поделиться

Я думал бы, что для значительной части Ваш или требования Вашего клиента должен продиктовать что точность и масштаб для использования. Например, для веб-сайта электронной коммерции я работаю над этим соглашения с деньгами в фунте стерлингов только, я был обязан сохранять его к Десятичному числу (6, 2).

0
ответ дан ayaz 23 November 2019 в 21:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: