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).
- Прост в использовании и совместим с любым языком.
- Меньший размер данных для хранения, чем строки или цифры.
- Легко поддерживать точность с помощью расчетов и применять округление на конечном выходе.