хранение денежных единиц без точки

A1x

Новичок
имеет ли смысл хранить денежные единицы без точки, т.е. в полях типа int, bigint?
помогает ли это бороться с ошибками округления?
 

флоппик

promotor fidei
Команда форума
Партнер клуба
да, имеет. да, помогает. для этого есть тип decimal.
 

A1x

Новичок
тут коллега хочет хранить деньги в bigint
как мне ему доказать что это плохая идея? или хорошая?

нутром чую что плохая
 

confguru

ExAdmin
Команда форума
A1x

Если есть дробные части - то хранить надо до 5-го знака после запятой, иначе никогда 0 не сойдется.
 

fixxxer

К.О.
Партнер клуба
денежные единицы вообще нельзя хранить в флоатах. только decimal, все вычисления только базой.

bigint это тот же decimal соответствующего размера - только точку ставить придется самому. :)
 

A1x

Новичок
или если делать вычисления в пхп то сначала сделать str_replace('.', '', $money), сделать вычисления а потом поставить точку назад
 

Dovg

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

str_replace('.', '', $money),
Щито?
У тебя есть уверенность, что decimal 10.000000 будет передано клиенту именно в таком виде, а не как 10?
 

A1x

Новичок
У тебя есть уверенность, что decimal 10.000000 будет передано клиенту именно в таком виде, а не как 10?
я предполагаю что все данные полученные извне, в т.ч. из базы, пхп считает строками
так что будет '10.000000'

вообще я за вычисления в базе :)
 

С.

Продвинутый новичок
Все денежные операции должны делаться строго в одном месте.
Иначе у тебя два соседних потока прибавят по пять рублей к одному и тому же счету, а в базе увеличения на 10 ты не получишь.
Совершенно без разницы, где считать деньги, если следовать четким правилам финансовых расчетов, приятых в данной стране/ведомстве/отрасли. Все эти страшилки про "пять рублей к одному и тому же счету" не имеют никакого отношения к жизни. Все теоретические возможные погрешности четко описаны и воспроизводимы незавсимо от вычислительной среды.

Например, если регламентировано, что промежуточный результат между двумя операциями передается с точностью до N десятых копейки, то он так и должен передаваться хоть на счетах, хоть в базе, хоть ПХПазе. Если сказано, что 0.5 округляется в меньшую сторону (реальное требование ЦБ РФ), значит так и надо округлять. В финансах нигде не может ни с того, ни с сего накопится нерагламентируемая погрешность.
 

AmdY

Пью пиво
Команда форума
Деньги нужно считать в одном месте и через враппер а-ля http://martinfowler.com/eaaCatalog/money.html Базе я бы такое не доверил, так как МНЕ труднее управлять там логикой., хотя, такими могут тбыть требования по безопасности.
 

fixxxer

К.О.
Партнер клуба
да не в безопасности дело а в целостности :) ну вон Dovg привел пример.
ладно, можно все грамотно завернуть в транзакции, с правильным isolation level и циклами на обломы, не вопрос, ошибиться тут проще, но сделать можно.
это если у тебя скажем java.
а если у тебя php с его неявным кастингом - ВЖО.

кстати, instance of class Money вполне может быть полем в умном орме, не вопрос ;)
 

Krishna

Продался Java
Если денежные операции это прибавление 5ти рублей, то да, может посчитаешь в базе. А если это пересчёт каких-нить страховых полисов, согласно календарным тарифам и скидочным акциям, то о..еете на своём plsql это считать. И масштабировать. И сопровождать. Базы сосут.
 

Krishna

Продался Java
По поводу денежных единиц, то важно различать цену и сумму. Сумма не может быть меньше 1коп, отсюда вопрос округления при делении 10 рублей на 1/3 и 2/3, например. См. паттерн Money по ссылке выше. Цена - может.
 

fixxxer

К.О.
Партнер клуба
Тебе с джавой хорошо рассуждать :D На похапе посчитай давай!
 

WMix

герр M:)ller
Партнер клуба
Krishna
все равно не убедил, денежные операции на веб страничках, это всеже чаще всего одновалютные операции, и с точностью до копейки,...
я за базу... за децимал...

все хуже чаще точность мешает, складывали мы заказы совсем недавно, русские посчитали сумму заказов в рублях и перевели по курсу... я при приеме сразу переводил каждый заказ в евро а после все сложил.... и естественно мы пришли к различным результатам!
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
Если денежные операции это прибавление 5ти рублей, то да, может посчитаешь в базе. А если это пересчёт каких-нить страховых полисов, согласно календарным тарифам и скидочным акциям, то о..еете на своём plsql это считать. И масштабировать. И сопровождать. Базы сосут.
а кто мешает написать на c/java/perl хранимую процедуру в базе? :)
 
Сверху