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

209

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

  • 13
    я использую deimal(10,2) ... вы можете настроить значения в зависимости от ожидаемого размера
  • 8
    Связанный вопрос - лучший тип данных для валюты ;).
Теги:
sqldatatypes
currency

10 ответов

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

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

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

См. Численные типы MySQL:

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

  • 3
    в чем может быть разница между десятичным и числовым типом данных для этого случая?
  • 54
    В MySQL decimal и numeric одинаковы.
Показать ещё 3 комментария
81

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

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

то есть. DECIMAL(10,2)

Изображение 884

Хорошее чтение

  • 3
    Возможно, это сбивает с толку, но ваш скриншот не соответствует вашему тексту ответа (точность, масштаб).
  • 0
    Я использую десятичную (10,2) для своей денежной стоимости, однако, когда я ставлю что-то вроде 867 000,00, оно сохраняется как 867. Что я делаю не так?
Показать ещё 2 комментария
26

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

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

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

  • 0
    Я использую десятичную (10,2) для своей денежной стоимости, однако, когда я ставлю что-то вроде 867 000,00, оно сохраняется как 867. Что я делаю не так?
  • 2
    @codeinprogress Неправильный региональный / десятичный разделитель?
23

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

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

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

  • 0
    Я помню, как профессор рассказывал мне подобное на курсе в университете по компьютерным системам. Меня учили, что самый точный способ - хранить в копейках (или центах) умножением на 100 и сохранением в виде целого числа и делением на 100, чтобы отобразить его пользователю. Я предполагаю, что это имеет преимущества с точки зрения точности и производительности системы базы данных.
  • 0
    Я думаю, это Scale Removing Method удаления весов, который устраняет беспокойство по поводу изменения масштаба по стране, например, когда 1020 (X) .03 (x) изменяется на 10 (x) .2003 (x) - то, что должен сделать пользовательский интерфейс Just поменял;).
Показать ещё 5 комментариев
13

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

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

  • 5
    Если вы собираетесь брать биткойны, вам понадобится 8 десятичных знаков, хотя большинство кошельков идут на mBTC, а это 3 en.wikipedia.org/wiki/Bitcoin
  • 0
    Не думайте, что этот ответ верный. opendata.stackexchange.com/a/10348/13983 @ david.ee есть источник для этого?
Показать ещё 2 комментария
3

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

  • 4
    Он не имеет ничего общего с «предпочтениями программиста» или тем, что вы «лично используете». Это продиктовано проблемной областью, для которой требуется десятичное число. Это не тот вопрос, в котором программист может использовать свои личные предпочтения.
  • 0
    Не думайте, что этот ответ верный. opendata.stackexchange.com/a/10348/13983
2

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

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

2

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

Decimal(19,4)

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

1

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

* Удушье *

Зачем?

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

Таким образом, он может представлять:

  • 0.123456789012345
  • 123456789012345.0

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

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

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

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

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

Конечно, использование double не обойтись без оговорок.

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

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

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

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

0

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

Ещё вопросы

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