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

178

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

Теги:
sqldatatypes

9 ответов

217
Лучший ответ

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

  • 51
    Вопрос о размере: в соответствии с MSDN ( msdn.microsoft.com/en-us/library/ms187746.aspx ), Decimal (10,4) и Decimal (19,4) оба используют 9 байт памяти, поэтому может хорошо прыгнуть за эти дополнительные 9 цифр шкалы.
  • 1
    Статья MSDN о SQL Server, но вопрос о MySQL. (Я встречался с разработчиками, которые думают, что оба одинаковы, так что лучше быть понятным.)
Показать ещё 2 комментария
48

Единственное, что вам нужно обратить внимание, это переход от одной базы данных к другой, вы можете обнаружить, что 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)
  • 8
    Я предполагаю, что это комментарий к посту Кибби, а не ответ ...
17

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

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

  • 7
    Это хороший момент - особенно в финансовых приложениях, «цена», безусловно, не подразумевает «деньги»
16

Ответ Assaf

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

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

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

  • 2
    Вот почему я рекомендовал десятичную (19,4). Может показаться излишним, но вы никогда не знаете, когда вам нужно будет хранить действительно большое количество в этой области.
  • 2
    @Kibbee: я бы не согласился с вами на наши требования до сегодняшнего дня. (За 6 лет (11,4) было прекрасно ...)
Показать ещё 1 комментарий
9

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

  • 0
    Как вы храните 6,125 (6 1/8)?
  • 0
    Я думаю, он будет хранить его как целое число 6125.
Показать ещё 2 комментария
6

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

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

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

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

5

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

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

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

0

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

0

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

Мой случай

  • decimal (13,4) без знака для записи денежных транзакций
    • эффективное хранилище (4 байта для каждой стороны десятичной точки) 1
    • GAAP-совместимый
  • decimal (19,4) unsigned для агрегатов
    • нам нужно больше места для итогов нескольких многомиллиардных транзакций.
    • полу-соответствие типу данных MS Currency не повредит 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
  • совместим с GAAP

Компромисс

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

Совместимый экстрим

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню