Есть сущность account, которая содержит внутри себя еще несколько сущностей. Эти сущности просто подробнее описывают основную сущность. Например, в аккаунте лежит ссылка на профиль, игровой прогресс, аватар и прочее. Все имеет отношение один к одному. То бишь у аккаунта не может быть больше одного профиля, аватара и т.д.
В качестве основной бд решили использовать postgres, а за тип хранения взяли jsonb.
Собственно вопрос : как правильно хранить вложенные сущности? В виде отдельных полей, которые будут являться типом jsonb? Или каждую сущность выносить в отдельную таблицу, которая будет связана посредством внешнего ключа с сущностью account?
В первом способе смущает то, что при изменении аватара, к примеру, придется сохранять весь аккаунт целиком (если только spring-jpa не умеет апдейтить сущность по изменившемуся полю). Да и в коде будет везде торчать accountRepository, что несколько смущает.
Во втором способе смущает наличие повторяющихся внешних ключей (отношение один к одному, да и сам ключ в виде uuid) и джоины.
Илья, а что с jsonb не так? На этапе прототипа это неплохой способ избежать головняков с джоинами и миграцией с одной схемы на другую. Я не спорю, что когда настанет момент и в дело вмешается бизнес, придется прибегнуть к нормализации, но пока это излишне, как мне кажется. Хотя тот же поиск предоставляет и jsonb.
Самые частые запросы на чтение будут, наверное. На текущем проекте 5кк аккаунтов, на новом планируется не меньше
protracer, есть у меня некоторые убеждения против nosql хранения в начале проекта, подкрепленные личным опытом. Кажется что json хорошо подходит для раннего прототипирования, можно не думать о консистентности, но по факту это вылезает в нарушение корректности работы системы. Потому что если правила не вводить то и система будет работать как угодно. Если разработчиков на проекте больше чем 1, то лучше фиксировать логику в схеме и типах, я считаю.
С другой стороны есть и оправданные кейсы для использования json, например сохранение нескольких наследников в одну таблицу. Когда общая часть хранится обычными полями а вариативная в json.
Во-вторых, как я понимаю у вашей ORM нет поддержки jsonb, значит любой запрос будет выгружать целиком строку. Если частота запроса небольшая то может это и не имеет значения. Если будет рост нагрузки это может стать узким местом. С другой стороны можно даже через ORM написать более-менее быстрый запрос просто выгружая лишь ту часть данных, которая нужна.
Илья, а есть ORM, которые это умеют в полной мере? Я пока наткнулся только на hibernate-types. Описываем сущность при помощи аннотаций и вперед. Сохранение работает, выборка по айдишнику тоже. А вот с частичными апдейтами и выборкой по условию уже проблема. Приходится писать чистые SQL-запросы