Задать вопрос
apiquestion
@apiquestion
Студент

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

В БД хранятся различные медиа, такие как: фильмы, сериалы (+сезоны, серии), музыка (+музыкальные группы, музыкальные альбомы, музыкальные треки) и т.д.
Все эти медиа хранятся в одной таблице и различаются по полю Type. Каждый тип медиа имеет как одинаковые свойства, так и различные. Напр: фильм может иметь продолжительность, а, например, у музыкальной группы продолжительности нету.
Вопрос: как лучше в приложении работать с такой таблицей? У меня есть 2 варианта:
1. Сделать одну общую модель для медиа и один репозиторий.
2. Сделать для каждого типа медиа свою модель и множество репозиториев. При этом все это будет привязано к одной таблице.
Какой вариант выбрали бы вы и почему?
  • Вопрос задан
  • 433 просмотра
Подписаться 2 Оценить Комментировать
Решения вопроса 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. Основано на том, как бы мне проще было понимать как все устроено.
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Похожие вопросы