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

Я хочу хранить много записей в базе данных MySQL. Все они содержат денежные ценности. Но я не знаю, сколько цифр будет вставлено для каждого.
Какой тип данных я должен использовать для этой цели?
VARCHAR или INT (или другие числовые типы данных)?

14 ответов

Решение

Поскольку деньги нуждаются в точном представлении, не используйте типы данных, которые являются только приблизительными, как float, Вы можете использовать числовой тип данных с фиксированной запятой для этого как

decimal(15,2)
  • 15 это точность (общая длина значения, включая десятичные разряды)
  • 2 количество цифр после десятичной точки

Смотрите MySQL Числовые типы:

Эти типы используются, когда важно сохранить точную точность, например, с денежными данными.

Ты можешь использовать DECIMAL или же NUMERIC оба одинаковы

Типы DECIMAL и NUMERIC хранят точные числовые значения данных. Эти типы используются, когда важно сохранить точную точность, например, с денежными данными. В MySQL NUMERIC реализован как DECIMAL, поэтому следующие замечания о DECIMAL в равной степени применимы к NUMERIC.: MySQL

т.е. DECIMAL(10,2)

Пример настроек

Хорошо для чтения

Я предпочитаю использовать BIGINTи сохраните значения умножением на 100, чтобы оно стало целым числом.

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

Внимание:
В основном мы не выступаем currency * currency умножение, в случае, если мы делаем это, то разделите результат на 100 и сохраните, чтобы он вернулся с правильной точностью.

Это зависит от ваших потребностей.

С помощью DECIMAL(10,2) обычно достаточно, но если вам нужно немного более точные значения, вы можете установить DECIMAL(10,4),

Если вы работаете с большими значениями, замените 10 с 19,

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

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

Мы используем double,

* удушье *

Зачем?

Потому что он может представлять любое 15-значное число без каких-либо ограничений на то, где находится десятичная точка. Все за жалкие 8 байтов!

Так что это может представлять:

  • 0.123456789012345
  • 123456789012345.0

... и все что между

Это полезно, потому что мы имеем дело с мировыми валютами, и double может хранить различное количество десятичных разрядов, с которыми мы, вероятно, столкнемся.

Один double поле может представлять 999,999,999,999,999s в японских иенах, 9,999,999,999,999,99s в долларах США и даже 9,999,999,999999999s в биткойнах

Если вы попытаетесь сделать то же самое с decimal, тебе нужно decimal(30, 15) который стоит 14 байтов.

Предостережения

Конечно, используя double не без предостережений.

Однако, это не потеря точности, как указывают некоторые. Даже если double само по себе может не быть внутренне точным для системы base 10, мы можем сделать это точным путем округления значения, которое мы извлекаем из базы данных, до ее значащих десятичных разрядов. При необходимости это так. (Например, если он будет выведен, и требуется представление базы 10).

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

  1. Выполнение сравнений на нем.
  2. Запись его обратно в базу данных.

Другой вид предостережения, в отличие от decimal(m, d) где база данных будет препятствовать программам вставлять число с более чем m цифры, таких проверок не существует с double, Программа может вставить введенное пользователем значение в 20 цифр, и в итоге она будет записана в виде неточного значения.

В то время, когда этот вопрос задавали, никто не задумывался о цене биткойна. В случае BTC, вероятно, недостаточно использовать DECIMAL(15,2), Если биткойн вырастет до 100 000 долларов или больше, нам понадобится как минимум DECIMAL(18,9) поддерживать криптовалюты в наших приложениях.

DECIMAL(18,9) занимает 12 байтов пространства в MySQL ( 4 байта на 9 цифр).

Если требуется соответствие GAAP или вам нужно 4 десятичных знака:

DECIMAL(13, 4) Поддерживает максимальное значение:

999 999 999,9999 долларов США

В противном случае, если 2 десятичных разряда достаточно: DECIMAL(13,2)

src: https://rietta.com/blog/best-data-types-for-currencymoney-in/

Действительно, это зависит от предпочтений программиста. Я лично использую: numeric(15,4) соответствовать Общепринятым принципам бухгалтерского учета (GAAP).

Хранение денег как BIGINT умножение на 100 или более с целью использования меньшего объема памяти не имеет смысла во всех "нормальных" ситуациях.

  • Чтобы оставаться в соответствии с GAAP, достаточно хранить валюты в DECIMAL(13,4)
  • Руководство MySQL гласит, что для хранения требуется 4 байта на 9 цифр. DECIMAL.
  • DECIMAL(13,4) представляет 9 цифр + 4 цифры после запятой (десятичные разряды) => 4 + 2 байта = 6 байтов
  • по сравнению с 8 байтами, необходимыми для хранения BIGINT.

Попробуйте использовать

Decimal(19,4)

это обычно работает с любой другой БД

Есть 2 допустимых варианта:

  1. использовать целое количество второстепенных единиц валюты (например, центов)
  2. представить сумму как десятичное значение валюты

В обоих случаях вы должны использоватьdecimalтип данных должен иметь достаточное количество значащих цифр. Разница может быть в точности:

  • даже для целочисленного количества второстепенных единиц лучше иметь дополнительную точность для аккумуляторов (учет накопления 10% комиссий от 1-центовых операций)
  • разные валюты имеют разное количество знаков после запятой, криптовалюты имеют до 18 знаков после запятой
  • Количество десятичных знаков может меняться со временем из-за инфляции.

Источник и другие предостережения и факты.

Используйте (илиNUMERIC- то же самое в MySQL).

Не использоватьDOUBLEили (особенноFLOAT). Это числа с плавающей запятой и двоичной точностью. (В OracleNUMBERtype также является числом с плавающей запятой, но с десятичной точностью, что подходит для денежных операций).

При этом необходимо указать общую точность и дробную часть. Например:

  • может хранить значения между-99,999,999.99и99,999,999.99.
  • может хранить значения между-999,999,999,999,999.9999и999,999,999,999,999.9999.

Выберите диапазон, который будет достаточно большим для вашего случая, но имейте в виду, что чем больше диапазон, тем больше памяти будет использоваться. В MySQLDECIMAL(10,2)всегда будет использовать 5 байт иDECIMAL(19,4)всегда будет использовать 9 байт, независимо от фактических значений, которые вы храните. Посмотрите это , чтобы узнать больше о том, какDECIMALвычисляется размер хранилища.

Умножает 10000 и сохраняет как BIGINT, например, "Валюта" в Visual Basic и Office. См. https://msdn.microsoft.com/en-us/library/office/gg264338.aspx

Другие вопросы по тегам