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

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

9 ответов


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


единственное, что вам нужно остерегаться, это если вы перейдете из одной базы данных в другую, вы можете обнаружить, что 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.


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

мой случай

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

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

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

компромисс

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

Совместимость Extreme

хотя 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 USD до 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. мы можем добавить еще одну цифру слева без каких - либо затрат-у нас есть decimal(28,4) для 15 байт
  5. теперь мы можем хранить 10 миллионов долларов США, выраженных в зимбабвийских долларах, или обезопасить себя от еще одной забастовки гиперинфляции, которая, надеюсь, не произойдет

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