Конечно, правильное проектирование это... правильно :) Впрочем, иногда денормализация БД – тоже осознанно выбранный подход. В примерах представлено что-то среднее.
Попробую подсветить пару моментов:
Если вынести stripe_customer_id в отдельную таблицу, основной User всё равно как бы будет знать о биллинге:
$user->getStripeCustomer();
Хотя в большинстве сценариев работы с пользователем этот релейшен вообще не нужен.
nullable password в этих историях (надеюсь) не означает "любой пользователь может существовать без пароля". Это лишь ещё один пример, когда общепринятый подход может быть изменён. Например, поддерживается несколько типов пользователей с разными конфигурациями (аля системный пользователь или пользователь, аутентифицирующийся через внешний провайдер). В пользователя без пароля я бы вообще логиниться не давал. Но опять же, это детали логики где-то в коде.
Как мне кажется, вьюшки решают немного другую, хотя и похожую, задачу.
Если нужен удобный read-model: сабсет полей, готовый join, ограничение прав на уровне БД, то вьюхи отлично подходят. Использовать вьюшки прям как сущности приложения пока не доводилось, тут не могу ничего сказать.
Если данные действительно имеют разный жизненный цикл, разные правила владения и независимо развиваются, то вынесение их в отдельные таблицы и связи по user_id – лучшее решение.
Просто бывают случаи, когда на уровне БД одна таблица уже выбрана осознанно и это нормально, но на уровне кода одна большая User-entity начинает становиться слишком жирной и неудобной для разных модулей.
С insert и NOT NULL ещё интереснее: предусмотрен механизм "валидирования" такой ситуации, чтобы заранее отловить проблему. Но тут как бы от базы не уйдешь – либо нужно эту колонку писать во всех сценариях, либо она всё-таки необязательная :) Ну либо можно сделать read-only модель под сценарий, когда запись не предполагается.
Спасибо за подробный комментарий.
Конечно, правильное проектирование это... правильно :) Впрочем, иногда денормализация БД – тоже осознанно выбранный подход. В примерах представлено что-то среднее.
Попробую подсветить пару моментов:
Если вынести
stripe_customer_idв отдельную таблицу, основнойUserвсё равно как бы будет знать о биллинге:Хотя в большинстве сценариев работы с пользователем этот релейшен вообще не нужен.
nullable
passwordв этих историях (надеюсь) не означает "любой пользователь может существовать без пароля". Это лишь ещё один пример, когда общепринятый подход может быть изменён. Например, поддерживается несколько типов пользователей с разными конфигурациями (аля системный пользователь или пользователь, аутентифицирующийся через внешний провайдер). В пользователя без пароля я бы вообще логиниться не давал. Но опять же, это детали логики где-то в коде.Как мне кажется, вьюшки решают немного другую, хотя и похожую, задачу.
Если нужен удобный read-model: сабсет полей, готовый join, ограничение прав на уровне БД, то вьюхи отлично подходят. Использовать вьюшки прям как сущности приложения пока не доводилось, тут не могу ничего сказать.
Да, это хорошее замечание.
Если данные действительно имеют разный жизненный цикл, разные правила владения и независимо развиваются, то вынесение их в отдельные таблицы и связи по
user_id– лучшее решение.Просто бывают случаи, когда на уровне БД одна таблица уже выбрана осознанно и это нормально, но на уровне кода одна большая
User-entity начинает становиться слишком жирной и неудобной для разных модулей.С
insertиNOT NULLещё интереснее: предусмотрен механизм "валидирования" такой ситуации, чтобы заранее отловить проблему. Но тут как бы от базы не уйдешь – либо нужно эту колонку писать во всех сценариях, либо она всё-таки необязательная :) Ну либо можно сделать read-only модель под сценарий, когда запись не предполагается.