Лучший тип данных для хранения денежных значений в базе данных MySQL
каков наилучший тип данных SQL для значений валют? Я использую MySQL, но предпочел бы независимый от базы данных тип.
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) без знака для агрегатов
- десятичное число(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Разумный Экстрим
- почему (27,4)?
- вы никогда не знаете, когда система должна хранить зимбабвийских долларов
сентябрь 2015 правительство Зимбабве заявило, что обменяет зимбабвийские доллары на доллары США по курсу от 1 доллара США до 35 квадриллионов зимбабвийских долларов 5
мы склонны говорить "да, конечно... Мне не нужны эти сумасшедшие цифры". Ну, зимбабвийцы тоже так говорили. Не так давно.
давайте представим, что вам нужно записать транзакцию в размере 1 млн долларов США в зимбабвийских долларах (возможно, маловероятно сегодня, но кто знает, как это будет выглядеть через 10 лет?).
- (1 млн USD) * (35 Quadrylion ZWL) = ( 10^6 ) * (35 * 10^15) = 35 * 10^21
- нам нужна:
- 2 цифры для хранения "35"
- 21 цифры для хранения нулей
- 4 цифр справа от десятичной точки
- это делает decimal(27,4) который стоит нам 15 байт для каждой записи
- мы можем добавить еще одну цифру слева без каких - либо затрат-у нас есть десятичная(28,4) для 15 байт
- теперь мы можем хранить 10 миллионов долларов США, выраженных в зимбабвийских долларах, или обезопасить себя от очередного удара гиперинфляции, который, надеюсь, не произойдет