apiquestion
@apiquestion
Студент

Множество сущностей, связанных с одной таблицей. Хорошо ли это?

В БД хранятся различные медиа, такие как: фильмы, сериалы (+сезоны, серии), музыка (+музыкальные группы, музыкальные альбомы, музыкальные треки) и т.д.
Все эти медиа хранятся в одной таблице и различаются по полю Type. Каждый тип медиа имеет как одинаковые свойства, так и различные. Напр: фильм может иметь продолжительность, а, например, у музыкальной группы продолжительности нету.
Вопрос: как лучше в приложении работать с такой таблицей? У меня есть 2 варианта:
1. Сделать одну общую модель для медиа и один репозиторий.
2. Сделать для каждого типа медиа свою модель и множество репозиториев. При этом все это будет привязано к одной таблице.
Какой вариант выбрали бы вы и почему?
  • Вопрос задан
  • 402 просмотра
Решения вопроса 1
copist
@copist
Empower people to give
Такой подход позволяет использовать сквозные ID и уменьшать количество связей в БД, не теряя целостности.
Например, не комментарии к фильмам, комментарии к записям блога, комментарии к товару в интернет магазине, комментарии в ленте пользователя, а иначе - "комментарии к записи базового типа".

Применение указанной тобой формы или, наоборот, нормализация её - это исходит из бизнес-требований. Структура таблиц следует из анализа предметной области, а не потому что "так правильно" или "так красивее". Если модель хранения подходит для конкретного применения - это хорошая модель. Зачастую моделей может быть несколько, приходится выбирать одну исходя из требований. Для реальных задач может даже пригодиться ненормализованные данные (JSON) хранить в реляционной базе. А вот если идеальная красивая понятная модель по третьей нормальной форме не способна реализовать потребность с учётом простоты, объёмов, надёжности, гибкости, быстроты - это никому не нужная модель.

С точки зрения объектно-ориентированного программирования - это как создать производный класс от родительского. Например, контрагенты - это либо физ лицо, либо юр лицо, но совсем не обязательно заводить под них две таблицы, можно обойтись одной, хотя в приложении такие сущности будут значительно отличаться.

Или вот ещё пример: в системе может быть пользователь (user), который вдруг может стать продавцом (supplier) или потребителем (customer). Их можно хранить в одной таблице (user = customer = supplier), если отличие - в каком-нибудь признаке "is_сustomer" и "is_supplier".
Если у них разные дополнительные атрибуты, например у продавца есть банковский счёт, а у покупателя - счёт в PayPal, у продавца - адрес хранения товара, а у покупателя - адрес доставки - то часть полей одной записи таблицы user используется для покупателя, а часть - для продавца
table `user`
  column `id` as primary key
  column `full_name` - общее поле
  column `is_supplier` - продавец
  column `is_customer` - покупатель
  column `shipping_address` - адрес доставки покупателя
  column `store_address` - адрес хранения продавца
  column `bank_account` - банковский счёт продавца
  column `paypal_account` - счёт покупателя

Схема условная

Но можно в одной таблице хранить только общие поля, а в дополнительных таблицах дополнительные поля. Сквозной ID сохраняется, даже нормальные формы работают.

table `user`
  column `id` as primary key
  column `full_name` - общее поле
  column `is_supplier` - продавец
  column `is_customer` - покупатель

table `supplier`
  column `id` as primary key & foreign key to `user`:`id`
  column `shipping_address` - адрес доставки покупателя
  column `bank_account` - банковский счёт продавца

table `customer`
  column `id` as primary key & foreign key to `user`:`id`
  column `store_address` - адрес хранения продавца
  column `paypal_account` - счёт покупателя

Схема условная
Тут указано, что их надо связывать отношением "один-к-одному".

Вообще грань очень незаметна. В любом случае в сложной схеме то на одни, то на другие грабли приходится наступать. Тут сквозные ID и избыток колонок в записи, а тут лишние UNION или JOIN, чтобы собрать вместе в одном отчёте. Если этот отчёт потребуется :)

Хранение сущностей в одной таблице относится к теме "Наследование в реляционных моделях" (не могу точно найти определение). Можно дополнительно прочитать тут:

www.sql.ru/forum/67152/nasledovanie-v-baze-dannyh
https://msdn.microsoft.com/ru-ru/library/bb531247.aspx
postgresql.ru.net/manual/ddl-inherit.html
https://habrahabr.ru/post/28023/
https://habrahabr.ru/post/322596/
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
@JuniorNoobie
Сижу в поддержке, пишу мелкие проекты
Лучше сделать для каждой сущности отдельную таблицу. Различных свойств всегда будет больше, чем одинаковых. Легче добавлять/изменять/удалять поля/столбцы. Проще добавлять/удалять сами сущности. Плюс портянку из эксплорера БД в 100-200 столбцов не очень интересно смотреть и очень неудобно с ней работать.
Ответ написан
Комментировать
EvilsInterrupt
@EvilsInterrupt
System programming, Reversing Engineering, C++
1.
>> Все эти медиа хранятся в одной таблице и различаются по полю Type
Вводя тип, различающий данные в таблице вы задаете условную логику. А это усложнение кода!

2.
Одна таблица одна сущность! Не экономьте на таблицах, если на это нет веских причин по performance.

3.
Есть объектно-ориентированные БД, которые позволяют вытащить общие части в аналог "базового класса". Посмотрите в эту сторону.

Это IMHO. Основано на том, как бы мне проще было понимать как все устроено.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы