Лучший тип данных для хранения значений валюты в базе данных MySQL - PullRequest
204 голосов
/ 10 марта 2009

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

Ответы [ 9 ]

223 голосов
/ 10 марта 2009

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

47 голосов
/ 10 марта 2009

Единственное, на что вам следует обратить внимание - если вы переходите с одной базы данных на другую, вы можете обнаружить, что 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)
17 голосов
/ 10 марта 2009

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

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

17 голосов
/ 10 марта 2009

Ответ Асафа

Зависит от того, сколько денег вы получили ...

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

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

11 голосов
/ 24 августа 2013

Для бухгалтерских приложений очень часто хранить значения в виде целых чисел (некоторые даже доходят до того, что говорят, что это only way). Чтобы получить представление, возьмите сумму транзакций (предположим, $ 100,23) и умножьте ее на 100, 1000, 10000 и т. Д., Чтобы получить необходимую точность. Так что если вам нужно только хранить центы и можно безопасно округлять в большую или меньшую сторону, просто умножьте на 100. В моем примере это будет 10023 как целое число для хранения. Вы сэкономите место в базе данных, и сравнение двух целых чисел будет намного проще, чем сравнение двух чисел с плавающей запятой. Мои $ 0,02.

8 голосов
/ 11 сентября 2014

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

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

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

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

5 голосов
/ 08 марта 2016

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

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

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

3 голосов
/ 01 апреля 2017

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

Мой кейс

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

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

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

Компромисс

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

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

Хотя MySQL позволяет использовать десятичную (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 млн. Долл. США) * (35 квадрилионов ZWL) = (10 ^ 6) * (35 * 10 ^ 15) = 35 * 10 ^ 21
  2. нам нужно:
    • 2 цифры для хранения "35"
    • 21 цифра для хранения нулей
    • 4 цифры справа от десятичной точки
  3. это составляет десятичное число (27,4), которое стоит нам 15 байтов для каждой записи
  4. мы можем бесплатно добавить еще одну цифру слева - у нас есть десятичное число (28,4) для 15 байтов
  5. Теперь мы можем хранить транзакцию на сумму 10 млн. Долларов США, выраженную в зимбабвийских долларах, или обеспечить защиту от очередной вспышки гиперинфляции, которая, как мы надеемся, не произойдет
0 голосов
/ 05 октября 2017

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

...