Ссылаюсь на moneyphp / деньги библиотека, которую я планирую использовать в одном из наших проектов для работы с валютами. Документация отличная, за исключением того, что она не затрагивает, как сохранить в базе данных. В нем говорится о кодировании денежного объекта в JSON, но хранение строк затрудняет выполнение запросов так же просто, как сравнение суммы или валюты.
Проходя через проблемы, я нашел немного дискуссий о доктрине, и она настолько специфична для доктрины, что я ничего не мог принести.
Задавая мой вопрос, вкратце: как хранить денежный объект, не теряя деталей? Я заинтересован в Postgresql, но с любой реляционной базой данных все в порядке.
Замечания: Я прочитал много разных способов сохранить деньги в базе данных, и они отличаются в том, как они делают. Меня интересует конкретный способ работы с этой конкретной библиотекой.
После утомительного прочтения множества разных тем, сообщений и др. Я пришел к выводу, что приемлемы только два пути (см. Замечательные комментарии в этот вопрос):
Конвертируйте все деньги в наименьшую единицу (например, центы) каждый раз, когда вы сохраняете в базу данных, и конвертируете при ее получении.
Используйте тип данных DECIMAL / NUMERIC с необходимой точностью (многие рекомендуют NUMERIC (15,4) при выполнении обычных операций или NUMERIC (15, 6) при выполнении операций обмена валюты)
Конечно, независимо от выбора, он должен быть связан со столбцом Валюта.
Я закончил с первым методом из-за эта библиотека (что не является оригиналом, когда я задал вопрос), что делает это очень легко. Вот объяснения от автора после того, как я создал вопрос:
Я могу только сказать вам, что я лично храню свои деньги в базе данных
как целое число, представляющее сумму в младших единицах (центах), и
необязательноCHAR(3)
для валюты, если приложение использует несколько
валюты (в противном случае валюта жестко закодирована в приложении).Таким образом, вы можете получить сумму в младших единицах как целое число:
$money->getMinorAmount()->toInt();
И вы можете получить деньги из целого числа, хранящегося в базе данных
с помощью:
Money::ofMinor($integerAmount, 'USD');
Других решений пока нет …