Похоже Money
типа не рекомендуется, как описано herePostgreSQL: Какой тип данных следует использовать для валюты?
Мое приложение должно хранить валюту, тип данных я буду использовать? Числовые, деньги или FLOAT?
Похоже Money
типа не рекомендуется, как описано herePostgreSQL: Какой тип данных следует использовать для валюты?
Мое приложение должно хранить валюту, тип данных я буду использовать? Числовые, деньги или FLOAT?
Numeric с принудительной точностью 2 единицы. Никогда не используйте float или float как тип данных для представления валюты, потому что, если вы это сделаете, люди будут недовольны, если итоговая цифра финансового отчета неверна + или - несколько долларов.
Тип денег как можно дальше указывается по историческим причинам.
Вот почему вы избегаете плавающей запятой. Даже Numeric будет иметь ошибки округления, если вы разделите все, что не делит на десять, независимо от того, какую точность вы используете. (Точность 2 - это плохая идея, так или иначе ... проверьте документы.) – Doradus
Ваш выбор:
integer
: хранить сумму в центах. Это то, что используют транзакции EFTPOS.decimal(12,2)
: хранить сумму с точностью до двух знаков после запятой. Это то, что использует большинство основных книг.float
: ужасная идея - неадекватная точность. Это то, что используют наивные разработчики.Вариант 2 является наиболее распространенным и простым в использовании. Сделайте точность (12 в моем примере, что означает 12 цифр), как большие, так и маленькие, что лучше всего подходит для вас.
Обратите внимание, что если вы агрегируете несколько транзакций, которые были результатом вычисления (например, с использованием обменного курса), в одно значение, имеющее бизнес-значение, точность должна быть выше, чтобы обеспечить точное значение макроса; подумайте о том, чтобы использовать что-то вроде decimal(18, 8)
, чтобы сумма была точной, а отдельные значения могут быть округлены до центровой точности для отображения.
Если вы работаете с любым видом обратного налога или иностранной валютой, вам нужно как минимум 4 десятичных знака, или вы потеряете данные. Поэтому 'numeric (15,4)' или 'numeric (15,6)' - хорошая идея. –
Существует 4-й вариант - использование String и использование эквивалентного десятичного типа без потерь в языке хоста. – ioquatix
Ваш источник никоим образом не является официальным. Это датируется 2011 годом, и я даже не признаю авторов. Если тип денег был «обескуражен», PostgreSQL скажет так в руководстве - which it doesn't.
Для более официальный источник, читайте this thread in pgsql-general (from just this week!) с заявлениями основных разработчиков, включая Д'Арси JM Cain (оригинальный автор типа денег) и Том Лейн:
В принципе, money
имеет свой (ограниченное) использует. Преимущество над numeric
составляет производительность.
decimal
- всего лишь псевдоним для numeric
в Postgres.
Связанный ответ (и комментарии!) О улучшениях в последних версии:
Лично мне нравится хранить валюту в качестве integer
представляющих центов. Это более эффективно, чем любой другой из указанных вариантов.
Существует несколько дискуссий по спискам рассылки, которые создают впечатление, что тип денег по крайней мере не рекомендуется, например: здесь: http://postgresql.nabble.com/Money-type-todos-td1964190.html#a1964192 plus чтобы быть справедливым: руководство для версии 8.2 ** ** ** назвало его устаревшим: http://www.postgresql.org/docs/8.2/static/datatype-money.html –
@a_horse_with_no_name: Ваша ссылка для темы из 2007, а также когда 8.2 была текущей версией, а тип 'money' был, по сути, устарел. Проблемы были исправлены, и этот тип был добавлен в более поздние версии. Лично мне нравится хранить валюту как «целое», представляющее Cents. –
Эрвин, вы можете подумать только с точки зрения базы данных. Однако, если вы комбинируете Postgresql + Java, это НЕ совсем хорошо (по моему опыту). Читая ваш комментарий, я использовал MONEY для большинства своих полей валюты, и теперь я получаю это исключение Java: «** SQLException произошло: org.postgresql.util.PSQLException: Плохое значение для типа double: 2,500.00 **». У меня есть googled и не нашел хорошего решения, поэтому я вхожу в скучную задачу поменять все на NUMERIC или DECIMAL сейчас! –
Я держу все свои денежные поля, как:
numeric(15,6)
кажется чрезмерным иметь что много знаков после запятой, но если есть хоть малейший шанс, что вы будете иметь дело с несколькими валютами вы будете нужна такая точность преобразования. Независимо от того, что я представляю пользователю, я всегда храню доллар. Таким образом, я могу легко конвертировать в любую другую валюту, учитывая коэффициент конверсии за день.
Если вы никогда не делаете ничего, кроме одной валюты, самое худшее здесь, что вы потратили немного места на хранение нулей.
У этого есть риск неправильных результатов из-за отсутствия усечения. Если ненулевые значения непреднамеренно просачиваются в оставшиеся десятичные разряды, например, поле цены, содержащее 0,3333333 доллара, тогда у вас может быть ситуация, когда система показывает результат того, что кто-то покупает 3 предмета по 0,33 доллара США на общую сумму до 1,00 долларов США вместо 0,99 доллара США. – Peteris
Perteris, так что вы предлагаете вместо этого? Независимо от того, насколько точность, которую вы бросаете на это округление, может быть проблемой. Я просто не нашел лучшего способа, даже если этот не идеален. –
Исправлена и усекалась там, где это уместно. Как только вы достигнете «сохраняемой» денежной стоимости, например. цена, предлагаемая клиенту, должна соответствовать соответствующим показателям, которые в большинстве случаев будут в целом центов в стандартной розничной среде. Если у вас разные потребности в бизнесе (например,цена на объемные товары на единицу) может быть другая установка точности, но вы должны рассматривать * презентацию вместе с памятью * - если вы показываете номер денег с x десятичными знаками (или наоборот, например, целыми тысячами), тогда вы также должны хранить его с * этой * точностью, не менее, но не более. – Peteris
Если вы прочитали всю цепочку, Numeric - это путь. – razpeitia