Я работаю с базой данных, которая имеет несколько типов (например, User
, Appointment
, Task
и т. Д.), Которые могут иметь ноль или более Notes
, связанных с каждым типом.
Возможные решения для реализации этих отношений:
- Полиморфная связь
- Отдельная таблица для каждого типа
Полиморфная связь
Многие считают, что это самое простое решение для реализации и, по-видимому, наиболее распространенная реализация для сред, которые следуют шаблону Active Record, я бы добавил таблицу, данные которой morphable
:
Мой notable_type
позволил бы мне различать тип (User
, Appointment
, Task
), к которому относится Note
, тогда как notable_id
позволил бы мне получитьотдельная запись type
в соответствующей таблице type
.
PROS:
- Легко масштабируется, больше моделей можно легко связать с полиморфнойкласс
- Пределы таблицы раздувания
- Результаты в одном классе, который может использоваться многими другими классами (СУХОЙ)
CONS
- Больше типов может усложнить запрос идороже по мере роста данных
- Не может иметь внешний ключ
- Отсутствие согласованности данных
Отдельная таблица для каждого типа
В качестве альтернативы я мог бы создатьтаблица для каждого типа, который отвечает за Notes
, связанный только с этим типом.Внешний ключ type_id
позволил бы мне быстро получить индивидуальную запись type
.
Многие онлайн воспринимаются как запах кода, многиев статьях предлагается избегать полиморфных отношений в пользу альтернативы (например, здесь и здесь ).
PROS:
- Позволяет нам эффективно использовать внешние ключи
- Эффективный запрос данных
- Поддерживает согласованность данных
CONS:
- Увеличивает раздувание таблицы, поскольку для каждого типа требуется отдельная таблица
- Результатов становится несколько классов, каждый из которых представляет отдельную
type_notes
таблицу
Мысли
Полиморфная связь, безусловно, является более простой из двух вариантов реализации, но отсутствие ограничений внешнего ключа и, следовательно, потенциальная возможность возникновения проблем согласованности, кажется неправильным.
Таблица на отношение notes
(user_notes
, task_notes
и т. д.) с внешними ключами кажетсяверным способом (в соответствии с шаблонами проектирования), но может привести к множеству таблиц (добавление других types
, которые могут иметь notes
или добавление типов, подобных notes
[например, events
]).
Мне кажется, что я выбрал упрощенную структуру таблиц, но отказался от внешних ключей и увеличил накладные расходы на запросы, или увеличил количество таблиц с той же структурой, но упростил запросы и допустил использование внешних ключей.
Учитывая мой сценарийчто из вышеперечисленного было бы более уместным или есть альтернатива, которую я должен рассмотреть?