Задать вопрос

Как лучше хранить денежные суммы в Postgres?

Условно говоря, у меня есть товар, цена которого может быть указана в рублях, долларах и биткоинах. Для классических валют было бы удобно использовать рекомендуемый тип numeric/decimal с точностью 2 для копеек/центов. Но условный биткоин требует значительно большей точности (один сатоши = 0.00000001 btc). Таким образом, я стою перед выбором:
1) использовать для хранения денежных сумм numeric с точностью 8 (100,00000000 руб)
2) воспользоваться тем, что PG позволяет вообще не указывать точность для numeric (скорее всего не бесплатно)
3) хранить все денежные суммы в минимальных расчетных единицах, используя тип integer.

В случае с третьим вариантом, если товар, например, стоит 100 рублей, то в колонке с ценой будет указано значение 10000 (умножаем на 100 копеек). При этом в справочнике валют для рублей укажем кратность 100. А для биткоина уже 10 000 000.

Естественно, прежде чем выдавать данные на клиента, нужно будет задействовать функцию, которая преобразует значения в стандартный вид (делим на кратность).

Аналогично, если клиент отправит 0,00001 btc, то перед сохранением в базу нужно будет выполнить "конвертацию" в минимальные расчетные единицы (0,00001*10000000=1000).

Есть ли какие-то преимущества у третьего варианта перед первыми двумя (кроме того, что тип int работает значительно быстрее, чем numeric). Кто-нибудь использовал его в реальных проектах?
  • Вопрос задан
  • 2597 просмотров
Подписаться 8 Простой Комментировать
Ответ пользователя tukreb К ответам на вопрос (4)
@tukreb
Вот так не нужно
https://wiki.postgresql.org/wiki/Don%27t_Do_This#D...

И всё Postresql умеет в numeric https://www.postgresql.org/docs/current/datatype-n...
up to 131072 digits before the decimal point; up to 16383 digits after the decimal point
Ответ написан
Комментировать