Я использую десятичный столбец для хранения денежных значений в базе данных, и сегодня мне было интересно, какую точность и масштаб использовать.
Поскольку предположительно символьные столбцы фиксированной ширины более эффективны, я подумал, что то же самое можно сказать и о десятичных столбцах. Это?
И какую точность и масштаб я должен использовать? Я думал о точности 24/8. Это излишне, недостаточно или хорошо?
Вот что я решил сделать:
- Сохраняйте коэффициенты конвертации (если применимо) в самой таблице транзакций в виде числа с плавающей запятой.
- Храните валюту в таблице счетов
- Сумма сделки будет
DECIMAL(19,4)
- Все вычисления, использующие коэффициент конверсии, будут обрабатываться моим приложением, поэтому я контролирую проблемы округления
Я не думаю, что плавающая ставка для конверсии является проблемой, так как она в основном для справки, и я все равно приведу ее к десятичной дроби.
Спасибо всем за ваш ценный вклад.
DECIMAL(19, 4)
популярный выбор, проверьте это, также проверьте здесь Форматы Мировой валюты, чтобы решить, сколько десятичных знаков использовать, надеюсь, поможет.Ответы:
Если вы ищете универсальный подход, я бы посоветовал
DECIMAL(19, 4)
это популярный выбор (быстрый Google подтверждает это). Я думаю, что это происходит от старого типа данных VBA / Access / Jet Currency, являющегося первым десятичным типом с фиксированной точкой в языке;Decimal
только в стиле «версия 1.0» (т.е. не полностью реализовано) в VB6 / VBA6 / Jet 4.0.Основное правило для хранения десятичных значений с фиксированной запятой - хранить как минимум еще одно десятичное число, которое фактически требуется для округления. Одной из причин сопоставления старого
Currency
типа в переднем конце сDECIMAL(19, 4)
типом в заднем конце было то, что уCurrency
банкиров было округление по природе, в то время какDECIMAL(p, s)
округление путем усечения.Дополнительное десятичное место в хранилище
DECIMAL
позволяет реализовать собственный алгоритм округления, а не принимать по умолчанию поставщика (и округление банкиров вызывает тревогу, если не сказать больше, для дизайнера, ожидающего, что все значения, заканчивающиеся на .5, округляются от нуля) ,Да,
DECIMAL(24, 8)
звучит как излишнее для меня. Большинство валют указаны в четыре или пять десятичных знаков. Я знаю ситуации , когда десятичная шкалу 8 (или более) в необходимой , но это где «нормальная» денежная сумма (скажем , четыре знака после запятой) была про rata'd, подразумевая точность десятичной должно быть соответственно уменьшено (также рассмотреть тип с плавающей точкой в таких обстоятельствах). И ни у кого сейчас нет таких денег, которые требуют десятичной точности 24 :)Однако, вместо того, чтобы подход «один размер подходит всем», некоторые исследования могут быть в порядке. Спросите своего дизайнера или эксперта по домену о правилах бухгалтерского учета, которые могут быть применимы: GAAP, EU и т. Д. Я смутно припоминаю некоторые внутригосударственные переводы в ЕС с четкими правилами округления до пяти десятичных знаков, поэтому они используются
DECIMAL(p, 6)
для хранения. Бухгалтеры обычно предпочитают четыре знака после запятой.PS Избегайте
MONEY
типа данных SQL Server, потому что он имеет серьезные проблемы с точностью при округлении, среди прочих соображений, таких как переносимость и т. Д. См . Блог Аарона Бертранда .Microsoft и дизайнеры языка выбрали округление банкира, потому что дизайнеры оборудования выбрали его [цитата?]. Например, оно закреплено в стандартах Института инженеров по электротехнике и электронике (IEEE). И дизайнеры оборудования выбрали это, потому что математики предпочитают это. Смотрите Википедию ; Перефразируя: издание «Вероятность и теория ошибок» 1906 года назвало это «правилом компьютера» («компьютеры», то есть люди, которые выполняют вычисления).
источник
DECIMAL(19, 4)
популярнее чемDECIMAL(19, 2)
? Большинство мировых валют имеют только два десятичных знака.Недавно мы внедрили систему, которая должна обрабатывать значения в нескольких валютах и конвертировать между ними, а также выяснили некоторые сложные вещи.
НИКОГДА НЕ ИСПОЛЬЗУЙТЕ НОМЕРА С ПЛАВАЮЩИМИ ТОЧКАМИ ДЛЯ ДЕНЕГ
Арифметика с плавающей запятой вносит неточности, которые могут быть не замечены, пока они не напортачили. Все значения должны храниться в виде целых чисел или типов с фиксированной десятичной дробью, и если вы решите использовать тип с фиксированной десятичной дробью, убедитесь, что вы точно понимаете, что этот тип делает под капотом (т. Е. Использует ли он внутренне целое число или число с плавающей запятой). тип).
Когда вам нужно сделать расчеты или преобразования:
При преобразовании числа с плавающей запятой обратно в целое число на шаге 3, не просто приведите его - используйте математическую функцию, чтобы сначала округлить его. Это обычно будет
round
, хотя в особых случаях это может бытьfloor
илиceil
. Знайте разницу и тщательно выбирайте.Храните тип числа рядом со значением
Это может быть не так важно для вас, если вы работаете только с одной валютой, но для нас это было важно при работе с несколькими валютами. Мы использовали трехсимвольный код для валюты, такой как USD, GBP, JPY, EUR и т. Д.
В зависимости от ситуации также может быть полезно хранить:
Знайте границы точности чисел, с которыми вы имеете дело
Для реальных значений вы хотите быть точным, как наименьшая единица валюты. Это означает, что у вас нет значений меньше цента, пенни, иены, фена и т. Д. Не храните значения с большей точностью, чем без причины.
Внутренне, вы можете иметь дело с меньшими значениями, в этом случае это другой тип значения валюты . Убедитесь, что ваш код знает, что есть что, и не перепутает их. Избегайте использования значений с плавающей запятой даже здесь.
Сложив все эти правила вместе, мы определились со следующими правилами. В рабочем коде валюты хранятся с использованием целого числа для наименьшей единицы.
В базе данных значения хранятся в виде строки в следующем формате:
Это хранит стоимость $ 25,00. Мы смогли сделать это только потому, что код, который работает с валютами, не обязательно должен находиться внутри самого уровня базы данных, поэтому все значения можно сначала преобразовать в память. Другие ситуации, без сомнения, поддаются другим решениям.
И в случае, если я не дал понять раньше, не используйте float!
источник
bigint
если вы собираетесь сортировать по сумме. И не тратьте свое время на 32-битный PHP при работе с большими целыми числами, обновитесь до 64-битного или Node.JS;)При обработке денег в MySQL используйте DECIMAL (13,2), если вы знаете точность значений ваших денег, или DOUBLE, если вы просто хотите получить достаточно хорошее и приблизительное приблизительное значение. Так что если ваше приложение должно обрабатывать денежные суммы до триллиона долларов (или евро или фунтов), то это должно работать:
Или, если вам нужно соблюдать GAAP, используйте:
источник
4 знака после запятой позволят вам хранить самые маленькие в мире денежные единицы. Вы можете сделать это дальше, если вам нужна точность микроплатежей (наноплатежей ?!).
Я тоже предпочитаю использовать
DECIMAL
типы денег, специфичные для СУБД, так как вы сохраняете логику в IMO приложения. Другой подход в том же духе заключается в простом использовании [длинного] целого числа с форматированием в ¤unit.subunit для удобства чтения (¤ = символ валюты) на уровне приложения.источник
Тип данных 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.
источник
Иногда вам нужно будет перейти на менее чем за цент, и есть международные валюты, которые используют очень большие демонизации. Например, вы можете взимать с ваших клиентов 0,088 цента за транзакцию. В моей базе данных Oracle столбцы определены как NUMBER (20,4)
источник
Если вы собираетесь выполнять какие-либо арифметические операции в БД (умножение тарифов и т. Д.), Вы, вероятно, захотите гораздо большей точности, чем предлагают здесь люди, по тем же причинам, по которым вы никогда не будете хотите использовать что-либо меньшее, чем значение с плавающей запятой двойной точности в коде приложения.
источник
BigDecimal
), но долгое время это была двойная точность (подумайтеdouble
вместоfloat
). Кроме того, произвольная точность имеет значительные потери производительности в некоторых случаях. Тестирование, безусловно, правильный подход.Если бы вы использовали IBM Informix Dynamic Server, у вас был бы тип MONEY, который является второстепенным вариантом для типа DECIMAL или NUMERIC. Это всегда тип с фиксированной запятой (тогда как DECIMAL может быть типом с плавающей запятой). Вы можете указать масштаб от 1 до 32 и точность от 0 до 32 (по умолчанию используется масштаб 16 и точность 2). Таким образом, в зависимости от того, что вам нужно хранить, вы можете использовать DECIMAL (16,2) - все еще достаточно большой, чтобы удерживать дефицит федерального бюджета США, с точностью до цента - или вы можете использовать меньший диапазон или больше десятичных знаков.
источник
Я думаю, что в значительной степени требования вашего или вашего клиента должны определять, какую точность и масштаб использовать. Например, для веб-сайта электронной коммерции, над которым я работаю, который касается только денег в фунтах стерлингов, я должен был указывать их в десятичном формате (6, 2).
источник
Поздний ответ здесь, но я использовал
что я правильно думаю, должно позволить до 99 999 999 999,99.
источник