PostgreSQL: Какой тип данных следует использовать для валюты?

Кажется, что тип Money обескуражен, как описано здесь

Мое приложение должно хранить валюту, какой тип данных я должен использовать? Числовые, деньги или FLOAT?

Ответ 1

Numeric с принудительной точностью 2 единицы. Никогда не используйте float или float, как тип данных, чтобы представлять валюту, потому что, если вы это сделаете, люди будут недовольны, если цифра финансового отчета неверна или + несколько долларов.

Тип денег только что оставлен по историческим причинам, насколько я могу судить.

Ответ 2

Ваш источник никоим образом не является официальным. Это относится к 2011 году, и я даже не узнаю авторов. Если бы тип денег был "обескуражен", PostgreSQL сказал бы об этом в руководстве, а это не так.

Для более официального источника прочитайте эту ветку в pgsql-general (только с этой недели!) С заявлениями основных разработчиков, включая D'Arcy JM Cain (первоначальный автор типа money) и Tom Lane:

В основном money имеют свое (ограниченное) использование. Преимущество перед numeric - производительность.

decimal просто псевдоним для numeric в Postgres.

Связанный ответ (и комментарии!) Об улучшениях в последних выпусках:

Лично мне нравится хранить валюту как integer представляющее центы. Это более эффективно, чем любой другой из упомянутых вариантов.

Ответ 3

Ваши варианты:

  • integer: сохранить сумму в центах. Это то, что используют транзакции EFTPOS.
  • decimal(12,2): сохранить сумму с точностью до двух знаков после запятой. Это то, что использует большинство основных книг.
  • float: ужасная идея - неадекватная точность. Это то, что используют наивные разработчики.

Вариант 2 является наиболее распространенным и простым в работе. Сделайте точность (12 в моем примере, что означает 12 цифр), как большие или малые, как лучше всего подходит для вас.

Обратите внимание: если вы агрегируете несколько транзакций, которые были результатом вычисления (например, с использованием обменного курса), в одно значение, имеющее бизнес-значение, точность должна быть выше, чтобы обеспечить точное значение макроса; подумайте о том, чтобы использовать что-то вроде decimal(18, 8), чтобы сумма была точной, а отдельные значения можно было округлить до точности для отображения.

Ответ 4

Я сохраняю все свои денежные поля как:

numeric(15,6)

Кажется чрезмерным иметь такое количество знаков после запятой, но если есть даже малейшая вероятность, что вам придется иметь дело с несколькими валютами, вам понадобится такая точность для конвертирования. Независимо от того, что я представляю пользователю, я всегда храню доллар. Таким образом, я могу легко конвертировать в любую другую валюту, учитывая коэффициент конверсии за день.

Если вы никогда не делаете ничего, кроме одной валюты, самое худшее здесь - это то, что вы потратили немного места на хранение нулей.

Ответ 5

Используйте 64-битное целое число, сохраненное как bigint

Я рекомендую использовать микро-доллары (или аналогичную основную валюту). Микро означает 1 миллион, поэтому 1 микродоллар = 0,000001 доллара.

  • Достаточная точность для обработки доли цента.
  • Хорошо работает при очень небольшой цене за единицу (например, показы рекламы или плата за API).
  • Прост в использовании и совместим с любым языком.
  • Меньший размер данных для хранения, чем строки или цифры.
  • Легко поддерживать точность с помощью расчетов и применять округление на конечном выходе.