TGViewer
Женя Янченко Женя Янченко @jane_yanchenko · 5.51K subscribers
Post #227 2.62K
Поговорим о деньгах?

А точнее о том, как их лучше хранить в БД.

Начинали мы как-то разработку нового проекта, и нужно было решить, как хранить деньги. Говорят, лучше в банке, но нам надо было в БД.
Складывать, вычитать, умножать и делить планировали в коде приложения.
База — PostgreSQL.

Я предложила вариант, с которым уже работала раньше:


✅ DECIMAL (он же NUMERIC) — тип данных, который рекомендуется для хранения денежных сумм и других величин, где важна точность.

NUMERIC(precision, scale)

precision — общее количество значимых цифр в числе, т. е. количество цифр по обе стороны десятичной точки.
scale — количество цифр в дробной части, справа от десятичной точки.

Например, число
23,5141 имеет precision = 6 и scale = 4.

Плюсы хранения в NUMERIC (DECIMAL):

➕ Высокая точность при расчетах (хотя расчеты планировалось делать в коде, а не в БД, полезно сразу иметь устойчивый тип данных, который хорошо мапится на аналогичный тип данных в коде)

➕ Интуитивно понятное представление значений:
видишь 575,34 — значит это 575 рублей 34 копейки (у нас были только рубли, без валют)

➕ Гибкость: если бы бизнес-требования изменились, и возникла необходимость хранить 3 или 4 знака после запятой, то можно просто поменять тип столбца через ALTER TABLE на numeric(20, 4), а значения пересчитывать не нужно — БД просто расширит точность и добавит лишние нули после запятой, ничего не ломая:
было 575,34 -> стало 575,3400

Минусы хранения в NUMERIC (DECIMAL):

➖ Операции со значениями numeric выполняются гораздо медленнее, чем с целыми числами

Коллега сказал:
— На прошлом месте мы использовали подход с хранением сумм как целых чисел в копейках. Может так сделаем?


✅ Хранение в виде целого числа minor units

Например, 57534 — это 575 рублей 34 копейки.

Хранить не обязательно в копейках, можно и в сотых долях копейки (4 знака после запятой) или других юнитах.

С точки зрения типа данных в БД можно использовать либо тип bigint (8 байт) либо если предполагаются очень большие суммы и маленькие единицы хранения - NUMERIC со scale = 0. Во втором случае в коде тоже нужно маппить на неограниченный по размеру тип целого числа, чтобы не произошло переполнения.

Плюсы хранения в виде целого числа minor units:

➕ Точные вычисления (о делении ниже)

➕ Высокая скорость вычислений, если используется bigint

Минусы хранения в виде целого числа minor units:

➖ Менее человеко-читаемое представление, выше вероятность ошибки при передаче данных в другие системы

➖ Меньше гибкости: в случае изменения требований (4 знака после запятой вместо 2) придется перезаписывать все значения:
было 57534 -> стало 5753400

➖ Дополнительные сложности с округлением при делении:

57534 копеек / 9 = 6392,666(6)
По правилам округления обычно 6392,666(6) -> 6393
Но при целочисленном делении дробная часть отбрасывается: 6392
(потеряли копейку)

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

— А ведь в PostgreSQL есть тип данных MONEY, может его?


❌ Тип MONEY

Это плохая идея, так как MONEY форматирован уже с кодом валюты, которая берется из локали (lc_monetary). Поменялась локаль, и показали пользователю вместо 575,34 ₽ -> $575.34 😅

Также внутри он устроен как целочисленный тип со свойственными ему проблемами с округлением. И хотя мы не собирались выполнять деление в БД, лучше не оставлять себе таких ограничений на будущее.
  • 👍 31
  • ❤ 18
  • 🔥 8
  • ❤‍🔥 6
  • 😁 1
More from @jane_yanchenko
  1. Sep 25, 2026В прошлой жизни, когда я была менеджером проектов, одним из первых мест работы у меня был…
  2. Sep 23, 2026Куда пропало обращение - развязка В прошлом посте у нас загадочно пропало обращение 58122.…
  3. Sep 23, 2026Куда пропало обращение Однажды от руководителя техподдержки пришло письмо, суть которого с…
  4. Sep 21, 2026🔗 Подборка постов про Кафку Как обещала на стриме, собрала посты про Кафку в удобное огла…
  5. Sep 21, 2026🎞 Готова запись стрима про Кафку: https://youtu.be/2aRKsD-MWDA Большое спасибо всем, кто…
  6. Sep 16, 2026Сегодня стрим по Кафке в 19:00 Планируем не в формате доклада, а в формате вопрос-ответ, ч…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →