Лучший тип данных для хранения денежных значений в базе данных MySQL


каков наилучший тип данных SQL для значений валют? Я использую MySQL, но предпочел бы независимый от базы данных тип.

9 197

9 ответов:

что-то вроде Decimal(19,4) обычно работает довольно хорошо в большинстве случаев. Вы можете настроить масштаб и точность в соответствии с потребностями чисел, которые вам нужно хранить. Даже в SQL Server я, как правило, не использую "money" как это нестандартным.

единственное, что вы должны следить за это, если вы мигрируете из одной базы данных в другую, вы можете обнаружить, что DECIMAL (19,4) и DECIMAL(19,4) означают разные вещи

( http://dev.mysql.com/doc/refman/5.1/en/precision-math-decimal-changes.html )

    DBASE: 10,5 (10 integer, 5 decimal)
    MYSQL: 15,5 (15 digits, 10 integer (15-5), 5 decimal)

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

Я работал над приложением цены акций, которое требовало расчета цены одного миллиона акций. Котируемая цена акций должна была храниться с точностью до 7 цифр.

ответ Асафа

зависит от того, сколько у тебя денег...

звучит легкомысленно, но на самом деле это уместно.

только сегодня у нас была проблема, когда запись не была вставлена в нашу таблицу ставок, потому что один из столбцов (GrossRate) установлен на десятичный (11,4), и наш отдел продуктов только что получил контракт на номера в каком-то удивительном курорте на Бора-Бора, которые продают за несколько миллионов тихоокеанских франков за ночь... что-то это никогда не было anticpated, когда схема базы данных была разработана 10 лет назад.

для бухгалтерских приложений очень часто хранить значения в виде целых чисел (некоторые даже заходят так далеко, что говорят, что это только путь). Чтобы получить представление, возьмите сумму транзакций (предположим, $ 100.23) и умножьте на 100, 1000, 10000 и т. д. чтобы получить точность вам нужна. Так что если вам нужно только хранить центы и можно безопасно округлить вверх или вниз, просто умножьте на 100. В моем примере это будет 10023 в качестве целого числа для хранения. Вы сэкономите место в базе данных и сравните два целых числа-это много проще, чем сравнивать два поплавка. Мои $0.02.

супер поздний вход, но GAAP-хорошее эмпирическое правило..

Если ваше приложение должно обрабатывать денежные значения до триллиона, то это должно работать: 13,2 Если вам нужно соблюдать GAAP (общепринятые принципы бухгалтерского учета) , то используйте: 13,4

обычно вы должны суммировать свои денежные значения в 13,4 перед округлением вывода до 13,2.

источник: лучший тип данных для хранения денежной стоимости в MySQL

вы могли бы использовать что-то вроде DECIMAL(19,2) по умолчанию для всех ваших денежных значений, но если вы будете хранить только значения ниже $1,000, это просто будет пустой тратой ценного пространства базы данных.

для большинства реализаций, DECIMAL(N,2) было бы достаточно, где значение N по крайней мере количество цифр перед . из самой большой суммы, которую вы когда-либо ожидали хранить в этом поле + 5. Поэтому, если вы никогда не ожидаете хранить какие-либо значения больше, чем 999999.99,DECIMAL(11,2) должно быть более чем достаточно (пока ожидания перемен).

если вы хотите быть GAAP совместимость, ты можешь пойти с DECIMAL(N,4), где значение N по крайней мере количество цифр перед . из самой большой суммы, которую вы когда-либо ожидали хранить в этом поле + 7.

Это зависит от характера данных. Вы должны обдумать это заранее.

мой случай

  • десятичное число (13,4) без знака для записи денежных операций
    • эффективное хранение (4 байта для каждой стороны десятичной точки в любом случае)1
    • GAAP совместимый
  • десятичное число (19,4) без знака для агрегатов
    • нам нужно больше места для суммирования нескольких многомиллиардных сделки
    • полу-соответствие с типом данных валюты MS не повредит 2
    • это займет больше места на запись (11 байт-7 слева и 4 справа), но это нормально, так как есть меньше записей для агрегатов 1
  • десятичное число(10,5) для обмена валют
    • они обычно цитируются с 5 цифр в целом, так что вы можете найти значения, как 1.2345 & 12.345, но не 12345.67890
    • это широко распространенная конвенция, но не кодифицированный стандарт (по крайней мере, для моего быстрого поиска знаний)
    • вы можете сделать его десятичным (18,9) с тем же хранилищем, но ограничения типа данных являются ценным встроенным механизмом проверки

Почему (M, 4)?

  • есть валюты, которые делятся на тысячу Пенни
  • есть эквиваленты денег, такие как" Unidad de Fermento"," CLF", выраженные с 4 знаками после запятой места 3,4
  • совместимость

компромисс

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

Совместимость Экстремального

хотя MySQL позволяет использовать decimal (65,30), 31 для масштаба и 30 для точности, похоже, являются нашими пределами, если мы хотим оставить опцию передачи открытой.

максимальный масштаб и точность в наиболее распространенных СУБД:

            Precision   Scale
Oracle      31          31
T-SQL       38          38
MySQL       65          30
PostgreSQL  131072      16383

6, 7,8,9

Разумный Экстрим

  1. почему (27,4)?
    • вы никогда не знаете, когда система должна хранить зимбабвийских долларов

сентябрь 2015 правительство Зимбабве заявило, что обменяет зимбабвийские доллары на доллары США по курсу от 1 доллара США до 35 квадриллионов зимбабвийских долларов 5

мы склонны говорить "да, конечно... Мне не нужны эти сумасшедшие цифры". Ну, зимбабвийцы тоже так говорили. Не так давно.

давайте представим, что вам нужно записать транзакцию в размере 1 млн долларов США в зимбабвийских долларах (возможно, маловероятно сегодня, но кто знает, как это будет выглядеть через 10 лет?).

  1. (1 млн USD) * (35 Quadrylion ZWL) = ( 10^6 ) * (35 * 10^15) = 35 * 10^21
  2. нам нужна:
    • 2 цифры для хранения "35"
    • 21 цифры для хранения нулей
    • 4 цифр справа от десятичной точки
  3. это делает decimal(27,4) который стоит нам 15 байт для каждой записи
  4. мы можем добавить еще одну цифру слева без каких - либо затрат-у нас есть десятичная(28,4) для 15 байт
  5. теперь мы можем хранить 10 миллионов долларов США, выраженных в зимбабвийских долларах, или обезопасить себя от очередного удара гиперинфляции, который, надеюсь, не произойдет

хотя это может быть поздно, но это будет полезно кому-то еще.Из моего опыта и исследований я узнал и принял десятичное число (19, 6).То есть при работе с php и mysql. при работе с большим количеством денег и валютный курс