Могут ли быть два типа связи одновременно между двумя таблицами?
Изучаем в университете дисциплину разработка баз данных. Стояла задача - разработать приложение с базой данных на 5-6 таблиц. Есть значит приложение - сервис по доставке. Есть таблица пользователей и таблица заказов. Изначально никаких проблем не возникло в однозначности проектирования - логично, что должна быть связь один-ко-многим. Т.е. у одного пользователя множество заказов, а заказ привязан к конкретному пользователю. И так, базы данных созданы, приложение почти доделано. Но тут, внезапно возникает необходимость в отслеживании у пользователя текущего заказа, т.к. заказ и корзина в условиях текущего приложения по сути одно и то же, только заказ может быть активным, либо нет. Абстрагировавшись от всей теории разработки БД, выбираю самое простое решение - добавление в таблицу пользователей поля "active_order_id", получая таким образом дополнительную связь между двумя таблицами один-к-одному.
Преподаватель с такой работой меня просто посылает, отказываясь даже смотреть на приложение, и оставшуюся часть БД, говоря, что нужно было раскрывать через промежуточную таблицу как многие-ко-многим...
Ума не приложу, куда в данную архитектуру пихать промежуточную таблицу, и зачем она тут вообще нужна? Конечно был вариант ещё в самом приложении писать массивные SQL запросы, делая выборку по связанным с пользователем заказам, проверяя у всех статусы.
Внимание, вопрос - может ли существовать подобная двойная связь между двумя таблицами. И если нет, то почему? Ведь производительность она даже улучшает, а так, не могу представить, каким образом она бы помешала расширению и усложнению архитектуры. Либо я чего-то не понимаю, либо это просто "нельзя, потому что не принято..."
Добавьте в таблицу заказов время создания, замените "активный" на "последний" - сразу станет проще.
Можете добавить туда же флаг - активен еще этот заказ или нет, если он может быть последним, но неактивным.
И выкиньте это нелепое поле из таблицы пользователей, не имеющей никакого отношения к жизни заказов.
Davidaa_WoW, довольно трудно объяснить человеку, который впервые взял в руки пилу, что легкость выпиливания квадратного колеса отнюдь не принципиальна. Может, вы просто поверите, что занимаетесь ерундой и потерпите, пока наберете побольше опыта и вам это тоже станет очевидным?
Davidaa_WoW, мягкий сарказм - это прекрасно, продолжайте в том же духе.
Но мне правда лень читать вам лекцию про управление сложностью, которую вы к тому же пока, скорее всего, не поймете и продолжите спорить. Давайте максимально просто: не мешайте мух с котлетами, не пишите в таблицы по возможности НИКАКИХ данных, которые относятся к данным ДРУГИХ таблиц. Только связи. Так вы избежите колоссального количества никому не нужных грабель.
может ли существовать подобная двойная связь между двумя таблицами
Запросто.
Например... ну, скажем, список интересов пользователя, причём один из интересов является "основным/приоритетным". Связь Пользователь - Интерес является типичной M:N, ибо интерес является мультиатрибутом, и использует связующую таблицу, тогда как связь Пользователь - Приоритетный интерес является связью 1:N, ибо приоритетный интерес является простым атрибутом, и связь оформляется дополнительным полем в таблице пользователей, ссылающимся на таблицу интересов.
Ну или то же на материале фильм-жанр... и т.д., и т.п.
Вы как-то не так трактуете термин "производительность". Усложнение схемы, добавление в неё любого объекта или свойства в принципе не способно улучшить производительность.
user
orders
Этого достаточно
у пользователя может быть куча заказов
В логике магазинов, (большинства)
Корзина это вообще отдельная сущьность, которая соотносится с заказом, но не полностью.
Так что реализуйте ее и не заморачивайтесь
А в моей архитектуре это не отдельная сущность. И поэтому одной связи не достаточно. Приложение уже готово и нормально функционирует, с такими связями. Так что моей вопрос остаётся открытым
Davidaa_WoW, ну ой, доказывайте вашему преподавателю почему вы выбрали именно эту архитектуру и почему он не прав. Ну я в общем то неуверен в вашем успехе, но как вариант
Владимир Коротенко, С отношениями с преподавателем я сам как-нибудь разберусь, спасибо. Вопрос здесь был в том, почему таких связей не может быть, а вы опять сводите к бессмысленному тезису: "сказали нельзя, значит нельзя".
Davidaa_WoW, вам привели контр пример. У пользователя может быть брольше одного активного заказа и сохранить нормально список активных заказов в одном поле не выйдет.
Если совсем нет времени переделывать, то можно было бы добавить флаг "активный заказ" в таблицу заказов и получать список таких заказов простым запросом по идентификатору пользователя и значению флага.
Davidaa_WoW, телепатов тут нет, не видя структуры я ничего не посоветую. А так на вьюшках много чего можно. Мысли вашего препода я кстати то же не читаю
Руслан ., Нет, у пользователя НЕ МОЖЕТ быть несколько активных заказов. Т.к. активный заказ = корзина. И она либо NULL, либо однозначно определена. Заказ перестаёт быть активным, сразу после оформления.
Davidaa_WoW, открою вам страшную тайну: корзина и заказ - это разные вещи, и на этапе, пока корзина активна (то есть может быть изменена) - никакого заказа еще просто нет.
Владимир Коротенко, Определять его можно и по полю status, о чём уже писал в комментариях к самому посту и приводил сам пример. Вопрос в том, почему бы себе не упростить жизнь через связь?
Davidaa_WoW, с точки зрения реализации вы можете делать как вам удобно. Но с точки зрения проектирования структуры БД атрибут "активный заказ" не является атрибутом сущности "пользователь".
То что вы реализовали называется денормализация, она применяется например в витринах данных для ускорения построения отчётов. Но если у вас курс по проектированию БД, то скорее всего от вас требуется спроектировать таблицы так, чтобы они соответствовали нормальным формам и именно поэтому ваш преподаватель не принял ваше решение.
Руслан ., Да, активный заказ не является атрибутом пользователя, он является просто внешним ключом заказов, создавая таким образом ту самую вторую связь один-к-одному)
Но так, спасибо, в целом стало понятнее. Единственное, что не могу понять момент - неужели, нигде во время разработки не появляются такие варианты, когда нужно две совершенно разных связи между таблицами, что такого нет ни только в теории, но и при беглом гуглении?
неужели, нигде во время разработки не появляются такие варианты, когда нужно две совершенно разных связи между таблицами, что такого нет ни только в теории, но и при беглом гуглении
А такая ситуация не является чем-то особенным, поэтому и не выделяется специально.
Пример - сотрудники и рабочие группы. Каждый сотрудник может входить в несколько групп, связь многие-ко-многим через промежуточную таблицу. У каждой группы есть руководитель, связь многие-к-одному через поле в таблице групп. Одна из групп является для сотрудника основной, связь многие-к-одному через поле в таблице сотрудников.
Davidaa_WoW, такое часто бывает нужно. Например это нужно при связи многие ко многим. Обычно
это решается добавлением отдельной таблицы, которая хранит эти связи.
Но тут, внезапно возникает необходимость в отслеживании у пользователя текущего заказа, т.к. заказ и корзина в условиях текущего приложения по сути одно и то же, только заказ может быть активным, либо нет.
Изменение техзадания требует забыть про всё ранее сделанное и начать сначала - то есть заново выполнить полный анализ предметной области с выделением сущностей-атрибутов-связей и построением ER-диаграммы. В ходе которого обнаружится, что схема претерпела радикальное изменение, и некоторые уже имеющиеся структуры (а лучше - все) следует спустить в унитаз и создать заново. Ибо в схеме появилась новая сущность, к тому же связанная с уже имеющейся сущностью отношением pattern-instance, которое даже при правильной реализации отличается повышенной проблемностью.
Абстрагировавшись от всей теории разработки БД, выбираю самое простое решение ..
Вы же вместо того, чтобы делать как надо, решили делать через одно место (причём это явно не голова). Как результат - неустранимое противоречие между теорией и получившейся поделкой-уродцем. На что собственно и указал преподаватель, отказавшись смотреть на полученное.
Чем скорее Вы смиритесь с тем, что следует начать работу заново, тем больше у Вас будет времени на её выполнение...