Собственно в который раз решил пересмотреть подход к хранению сумм и стандартизировать его для себя во веки веков. Идеального решения которое совсем никогда не доставляет боли пока не встречал/не выработал.
К самим числам подход простой: decimal(19,4)
Справочник валют тоже достаточно простоый:
id, code, description, symbol, decimals,min_value
840, 'USD', 'Доллар США', '$', 0.01, 0.01
Хотя id/code по суди оба могут выстуать как id и ипользование char(3) чуть нагляднее если лазить руками в базу. Тут в раздумиях.
А вот суммы хранить можно по разному:
- Как три поля: price, currency_id, date (ну либо брать дату документа/текущую дату в зависимости от типа записи)
- Как составной тип: create type money as (value decimal(19,4), currency_id int, date date default null)
- 9 лет назад была вот такая штука
https://github.com/samv/pg-currency но развития не получила, а очень жаль.
Очевидно, что хранение в комплексном типе упрощает вставку/вывод но усложняет join'ы/преобразования.
Хранения в разных валютах полностью исключает любую агрегация средствами СУБД (как раз эту проблему и был призван решить pg-currency), ну или очень серьезно усложняет, приведение к одной несет в себе потерю точности. В теории для комплексного типа можно написать функции преобразования, но не уверен насколько это реализуемо в полном объеме.
Однако, с точки зрения протокола обмена с frontend'ом любую сумму все же лучше представлять как объект.
Поделитесь свежим опытом?