Как хранить деньги в приложении

Главное правило

Исходить из задач бизнеса. Обговорить какая точность нужна. Храним до 5 знаков после запятой, либо достаточно 2-3 знаков, либо копейки вообще не нужны.

Заранее согласовать правило округления и использовать только его.

После того как приняли стандарт хранения денег, и в приложении и в базе данных надо следовать этим правилам.

Best practice по хранению денег в базе данных(на примере mysql)

Если бы мне давали 10 центов каждый раз когда я вижу как кто-нибудь использует FLOAT для хранения денег, то у меня бы уже было $999.997634

Bill Karwin
  1. Не хранить деньги как float, double, real. Эти типы данных с плавающей запятой могут хранить огромные значения, но точность вычислений не высока.
  2. Подходящие типы numeric, decimial и integer(в некоторых случаях), biginteger. У каждого варианта есть свои плюсы и минусы.
    • Если выбираем numeric , decimial (5,2) то в базе данных деньги хранятся в естественном виде(1200.50). В скобках указывается кол-во знаков до и после запятой. У этого способа хранения есть минус, если у вас предусмотрена работа с несколькими валютами, то придется ориентироваться по валюте, которая имеет наибольшее число знаков после запятой. Например в системе кроме рублей есть еще Бахрейский динар, который имеет 3 знака после запятой. Тогда и рубли будут храниться 1200.500 что для рублей будет избыточно.
    • Если выбираем integer, biginteger то храним деньги в минимальной дробной денежной единице валюты. Т.е. если у нас рубли, то 1200.50 руб. будет сохранено в базе как 120050.

Best practice по работе с деньгами в php

  1. Если в БД деньги хранятся в decimial:
  2. Если в БД деньги хранятся в biginteger:
    • Постоянный перевод в копейки при сохранении в БД и перевод копеек в рубли при получении данных. Например на счет надо сохранить сумму 100.50 руб. Умнажаем её на 100 и сохраняем в бд. Когда вынимаем из бд, делаем деление на 100.
    • Нет плавающей точки, погрешности исключены.
    • Операции с целочисленными значениями быстрее.
    • Минусы: постоянное умножение и деление.

Библиотеки

Можно воспользоваться готовым решением — это реализация класса «Деньги», довольно популярное решение, имеет более 2.5К звёзд.

Ссылки:

  1. https://toster.ru/q/23947
  2. https://stackoverflow.com/questions/628637/best-data-type-for-storing-currency-values-in-a-mysql-database

Рекомендуем к прочтению



1 Комментарий

Оставить комментарий

Этот сайт защищен reCAPTCHA и применяются Политика конфиденциальности и Условия обслуживания применять.

Срок проверки reCAPTCHA истек. Перезагрузите страницу.