Re[13]: и еще один вопрос по реляционной структуре
От: Qulac Россия  
Дата: 30.10.24 17:59
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Здравствуйте, Qulac, Вы писали:


PD>>>Вот только с UNION вопрос. Таблицы-то сильно разные. В них вообще может не быть одинаковых по смыслу полей, кроме ID, и то, если он в них есть(они могли бы использовать ID базовой как свой PK). Что брать-то ? И как потом определить, откуда взяли ?


Q>>В чем проблема нужный запрос написать, sql поддерживает условные операторы CASE и IIF?


PD>Да ради бога, а что брать-то и как определить, откуда взяли


PD>В таблице группы есть одно поле number int. И FK на базовую

PD>В таблице факультет есть одно поле name varchar. И FK на базовую, конечно

PD>Что брать-то ?


Вот так например:
 DECLARE @student_id INT = 2;
declare @faculty varchar(50);
declare @group varchar(50);

   -- если у студента нету ссылки на факультет, то он зачислен в группу и все данные получаем по связи от группы
   if((select count(*) from students inner join students_sets on students.students_set_id=students_sets.students_set_id 
    inner join faculties on faculties.faculties_id=students_sets.students_set_id 
     where students.students_id = @student_id) = 0)
     begin
     set @group = (select groups.number 
       from students 
       inner join students_sets on students.students_set_id=students_sets.students_set_id 
       inner join groups on groups.groups_id = students_sets.students_set_id 
       where students.students_id=@student_id)
     set @faculty = (select faculties.Name 
     from students inner join students_sets on students.students_id=students_sets.students_set_id 
     inner join groups on students.students_set_id=groups.groups_id 
     inner join faculties on faculties.faculties_id= groups.faculties_id 
     where students.students_id=@student_id)
     end
   else
    begin
     set @faculty = (select faculties.Name 
     from students inner join students_sets on students.students_id=students_sets.students_set_id 
     inner join faculties on faculties.faculties_id=students_sets.students_set_id 
     where students.students_id = @student_id);
     end


select @faculty as 'Факультет', @group as 'группа'


Программа – это мысли спрессованные в код
Re[14]: и еще один вопрос по реляционной структуре
От: Pavel Dvorkin Россия  
Дата: 31.10.24 01:33
Оценка:
Здравствуйте, Qulac, Вы писали:

Q>Вот так например:


<skipped>

Ну не знаю. Может быть, это и будет работать, но нужно серьезное тестирование.
Вижу 2 таблицы : students и students_sets. Первая, полагаю, все студенты, а вторая что такое ?
И где тут базовая (в терминах предыдущих твоих постингов) таблица ? Или она и есть students_sets ?

В общем, рекомендовать это студентам я бы не стал. ИМХО слишком тяжелая артиллерия для , в общем-то, простой ситуации. В конце концов 2 FK от студента на группу и факультет хоть и не очень хорошо с точки зрения канонов, но терпимо.

Ну и концептуально мне это решение не нравится. Получается, что таблицы факультет и группа — братья и оба "потомки" от базовой. А по смыслу все же факультет : группа == parent:child. И не стоит ради того, чтобы решить локальную проблему, портить структуру .

А вот это решение вообще снимает все проблемы легко и изящно

https://rsdn.org/forum/db/8843919.1
Автор: m2user
Дата: 30.10 15:51
With best regards
Pavel Dvorkin
Отредактировано 31.10.2024 3:34 Pavel Dvorkin . Предыдущая версия .
Re[2]: и еще один вопрос по реляционной структуре
От: Pavel Dvorkin Россия  
Дата: 31.10.24 02:47
Оценка:
Здравствуйте, m2user, Вы писали:

M>Виртуальная группа (одна на каждый факультет) в таблице `group` c FK на faculty.

M>Помещать туда студентов без группы.
M>В таблицу `group` добавить колонку с типом группы (обычная или имеет особый смысл).

Один недостаток у этого решения все же есть.
Курс , на котором студенты, достаточно поместить в `group`, так как вся группа на одном курсе.
Для этой виртуальной группы так не получится. Придется курс помещать в student, а там это лишнее, в общем-то. Для студентов внутри группы он не нужен.
Можно создать не одну, а 4 или 5 виртуальных групп, каждая по своему курсу. В этом даже какая-то логика есть — студенты, вышедшие из общего процесса на таком-то курсе. Если кто-то из них вернется даже через несколько лет — вся информация на месте. Вышел из общего процесса на 3 курсе, туда и надо вернуть. Так сказать, заморозка участия на неопределенный срок.
With best regards
Pavel Dvorkin
Re[15]: и еще один вопрос по реляционной структуре
От: Qulac Россия  
Дата: 31.10.24 05:19
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Здравствуйте, Qulac, Вы писали:


Q>>Вот так например:


PD><skipped>


PD>Ну не знаю. Может быть, это и будет работать, но нужно серьезное тестирование.

PD>И где тут базовая (в терминах предыдущих твоих постингов) таблица ? Или она и есть students_sets ?

Да.

PD>В общем, рекомендовать это студентам я бы не стал. ИМХО слишком тяжелая артиллерия для , в общем-то, простой ситуации. В конце концов 2 FK от студента на группу и факультет хоть и не очень хорошо с точки зрения канонов, но терпимо.


Применять это на практике или нет — это уже другой вопрос, но способ есть для случаев когда у сущности могут быть взаимоисключающие связи с другими сущностями.

PD>Ну и концептуально мне это решение не нравится. Получается, что таблицы факультет и группа — братья и оба "потомки" от базовой. А по смыслу все же факультет : группа == parent:child. И не стоит ради того, чтобы решить локальную проблему, портить структуру .


Собственно это и есть наследование поведения — и факультет и группа могут содержать в себе студентов, т.е. у них есть общность.

PD>А вот это решение вообще снимает все проблемы легко и изящно


PD>https://rsdn.org/forum/db/8843919.1
Автор: m2user
Дата: 30.10 15:51


Мое дело было предложить вариант решения. Вообще как известно используя реляционную модель можно смоделировать любую структуру данных в нормальной форме. Как это сделать в этом случае?
Программа – это мысли спрессованные в код
Отредактировано 31.10.2024 5:46 Qulac . Предыдущая версия .
Re[16]: и еще один вопрос по реляционной структуре
От: Pavel Dvorkin Россия  
Дата: 31.10.24 08:04
Оценка:
Здравствуйте, Qulac, Вы писали:


Q>Собственно это и есть наследование поведения — и факультет и группа могут содержать в себе студентов, т.е. у них есть общность.


Ну в общем-то да. В императивном языке явно напрашивается interface StudentHolder и Group и Faculty extends его.

А в то же время, если допустить, что только Group может иметь студентов, то Faculty может его и не имплементировать, что ничему не помешает, так как косвенно итерацией по группам мы все их получим.
Ну а если все же и сам Faculty может их иметь (то есть без виртуальной группы), то не скажу, что и это решение мне нравится.

Хотя...

Рассмотрим аналогичный пример. Товары в магазине в категориях (мясные, молочные, растительные...). Пусть каждый товар принадлежит только одной категории. Но есть товары, ни в одну категорию не входящие.
Тут возражений концептуальных нет.
А по сути то же самое.



PD>>А вот это решение вообще снимает все проблемы легко и изящно


PD>>https://rsdn.org/forum/db/8843919.1
Автор: m2user
Дата: 30.10 15:51


Q>Мое дело было предложить вариант решения. Вообще как известно используя реляционную модель можно смоделировать любую структуру данных в нормальной форме. Как это сделать в этом случае?


Не знаю, я не большой специалист в теории БД и тем более в реляционной алгебре. Может, другие скажут ?
With best regards
Pavel Dvorkin
Re: и еще один вопрос по реляционной структуре
От: swimmers  
Дата: 31.10.24 08:27
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Пусть та же система, что и тут


Предлагаю подумать насчет хранения истории изменения принадлежности студента к группе.
Многие вопросы, даже еще не озвученные, снимутся.
Но, как обычно бывает, возникнут другие )))
Re[3]: и еще один вопрос по реляционной структуре
От: m2user  
Дата: 31.10.24 08:37
Оценка:
PD>Можно создать не одну, а 4 или 5 виртуальных групп, каждая по своему курсу. В этом даже какая-то логика есть — студенты, вышедшие из общего процесса на таком-то курсе. Если кто-то из них вернется даже через несколько лет — вся информация на месте. Вышел из общего процесса на 3 курсе, туда и надо вернуть. Так сказать, заморозка участия на неопределенный срок.

Почему бы и нет — по одной виртуальной группе на каждый курс каждого факультета.

Кстати вариант с таблицами отношений (student-group, group-faculty) мне кажется более гибким, т.к. позволяет при необходимости поместить студента в несколько групп.
Но виртуальные группы там тоже будут нужны для связи студента без группы и факультета.
Re[2]: и еще один вопрос по реляционной структуре
От: Pavel Dvorkin Россия  
Дата: 31.10.24 09:29
Оценка:
Здравствуйте, swimmers, Вы писали:

S>Предлагаю подумать насчет хранения истории изменения принадлежности студента к группе.

S>Многие вопросы, даже еще не озвученные, снимутся.

Несомненно. Если вводить историю (версионность), то ее надо делать не только для принадлежности студента к группе, но и для самих групп.

Например, когда я учился, номер группы формировался так

код_факультета последняя_цифра_года_поступления номер_группы_в_этом году.

Поэтому, скажем, 822 группа — это и группа набора 1922 года, и 1932 года, ... 2022 года.

А еще после 3 курса все группы ликвидировали и распределили по новым группам в соответствии со специализацией

Были группы 821-823, а стали 821-825, при этом общего у прежней 822 и новой 822 ничего не было, хотя какие-то студенты и были до в 822 и оказались после в 822.

Ну а если дальше пойти — переименования, слияния и разделения факультетов...

Но это уже совсем другая задача.
With best regards
Pavel Dvorkin
Re[4]: и еще один вопрос по реляционной структуре
От: Pavel Dvorkin Россия  
Дата: 31.10.24 09:33
Оценка:
Здравствуйте, m2user, Вы писали:

M>Кстати вариант с таблицами отношений (student-group, group-faculty) мне кажется более гибким, т.к. позволяет при необходимости поместить студента в несколько групп.


Для student-group вполне согласен. Более того, порой он единственно возможный, например, для спортшколы, где вполне реально, что кто-то входит в 2+ секции

Для group-faculty — сомневаюсь. Не могу представить группу, принадлежащую 2 факультетам одновременно.
With best regards
Pavel Dvorkin
Re: и еще один вопрос по реляционной структуре
От: sergeya Ниоткуда http://blogtani.ru
Дата: 31.10.24 11:29
Оценка: +1
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>В итоге у студента должно быть 2 FK — на группу и факультет. Но группа имеет FK на факультет. Получается, что студент фактически имеет 2 FK на факультет — один явно, а другой косвенно, через свой FK на группу и FK группы на факультет.


Дополню, что студет может одновременно учиться на двух (и более) факультетах.

В нашем пединституте можно было например паралельно с физматом обучаться на инязе.
Закон разрешает студентам одновременно осваивать несколько образовательных программ.
Мобильная версия сайта RSDN — http://rsdn.org/forum/rsdn/6938747
Автор: sergeya
Дата: 19.10.17
Re[3]: и еще один вопрос по реляционной структуре
От: paucity  
Дата: 31.10.24 12:30
Оценка: +2
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Но это уже совсем другая задача.


Ты бы начал с формализации требований/ТЗ/спецификаций (назови как хочешь) для твоей учебной задачи -- основные моменты без растекания.

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

Да и проверять и оценивать работы студентов будет проще.
Re[4]: и еще один вопрос по реляционной структуре
От: Pavel Dvorkin Россия  
Дата: 31.10.24 13:02
Оценка:
Здравствуйте, paucity, Вы писали:

P>Ты бы начал с формализации требований/ТЗ/спецификаций (назови как хочешь) для твоей учебной задачи -- основные моменты без растекания.


P>Например, если в требованиях будет зафиксированно, что студент может быть только в одной группе и историю переводов из группы в группу, или с факультета на факультет хранить не надо, то и вопросов меньше.


Да, ты прав, я как-то не подумал. Надо было с самого начала объяснить, что это модельная учебная задача, а вовсе не для production.

Исправляюсь.

В общем, есть у меня учебное упражнение по основам SQL а потом MyBatis и Hibernate.

Задача простая — факультет, группы, студенты, предметы

Цель — освоить SQL и остальное. PK, FK, WHERE всякие, JOIN и т.п. В общем, основы SQL , начальный курс. Без триггеров и SP.

Ну и many :1 (student : group) и many:many (group:subject).

Институт я в этой модели опустил. Лес факультетов с группами и студентами в них. Естественно, только текущее состояние, никакой истории.

А с другой стороны, правила тут должны быть именно те, что в реальности. Предметная область студентам очень уж хорошо знакома

И вот я подумал, не расширить ли задачу, добавив институт. В исходной задаче принадлежность студентов замалчивается. Они члены групп или не члены, а те, что не члены, явно ни чему не принадлежат.

Ну и возникли 2 вопроса. Первый — про единственную запись в таблице институт, а вторая — к чему принадлежат студенты, не входящие в группы.
With best regards
Pavel Dvorkin
Отредактировано 31.10.2024 13:07 Pavel Dvorkin . Предыдущая версия . Еще …
Отредактировано 31.10.2024 13:07 Pavel Dvorkin . Предыдущая версия .
Re[2]: и еще один вопрос по реляционной структуре
От: Pavel Dvorkin Россия  
Дата: 31.10.24 13:06
Оценка:
Здравствуйте, sergeya, Вы писали:

S>Закон разрешает студентам одновременно осваивать несколько образовательных программ.


Да, верно, я как-то забыл об этом.

Лет 25 назад был у меня один студент, мой курсовик. Доучился до 3 курса, а потом сообщил мне, что он поступил еще на заочное на юрфак.
Я ему сказал, что не получится у него, времени не хватит. Он ответил, что хватит.
Через полгода мы встретились, и он сказал : "Вы были правы". Пришел он забрать документы.
Больше я его не видел.
With best regards
Pavel Dvorkin
Re: и еще один вопрос по реляционной структуре
От: BlackEric http://black-eric.lj.ru
Дата: 31.10.24 15:41
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Пусть та же система, что и тут


PD>https://rsdn.org/forum/db/8843633.1
Автор: Pavel Dvorkin
Дата: 30.10 04:24


PD>пусть есть таблица institute с одной строкой. Или как-то иначе. Это здесь не обсуждаем.


PD>Есть факультеты. Таблица faculty с FK (или без него, как хотите) на institute


PD>На факультете есть группы. Таблица `group` с FK на faculty.


PD>А еще есть студенты. Таблица student и вот тут вопрос


Один и тот же человек может одновременно учиться на разных факультетах. Дневной + заочка. Или на одном, но на разных специальностях.

Поэтому связь студента с факультетом и группой через промежуточную таблицу. Там связь M:N.
Да каждый человек имеет сслылку на хотя бы 1 факультет (обязательно). И возможно на группу, а если в академе, то не имеет ссылки на группу, только на факультет.
И еще нужно разрулить когда он на одно и том же факультете учится на одной специальности, а на 2 а академе.
Нужен отдельной таблице список студентов в академе получается.
Итого
Факультеты
Группы
Академы
Студенты.
И таблицы для связей всего этого. Как-то так.
https://github.com/BlackEric001
Re[2]: и еще один вопрос по реляционной структуре
От: Pavel Dvorkin Россия  
Дата: 31.10.24 16:07
Оценка:
Здравствуйте, BlackEric, Вы писали:

Уточнил тут

https://rsdn.org/forum/db/8844528.1
Автор: Pavel Dvorkin
Дата: 31.10 16:02
With best regards
Pavel Dvorkin
Re[3]: и еще один вопрос по реляционной структуре
От: Qulac Россия  
Дата: 31.10.24 22:17
Оценка: +1
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Здравствуйте, BlackEric, Вы писали:


PD>Уточнил тут


PD>https://rsdn.org/forum/db/8844528.1
Автор: Pavel Dvorkin
Дата: 31.10 16:02


Еще комментарий по первоначальному варианту. С начала нужно разобраться: А есть ли тут проблема вообще? Большинство сделают так: один fk у студента постоянно указывает на факультет, в который он зачислен, второй на группу если он в ней учится. Казалось бы тут есть избыточность: студент имеет имеет две связи с факультетом: одну прямую, вторую через группу. Но, это разные ассоциации. Что бы это определить нужно попытаться им дать названия и(или) назвать роли сущностей участвующих в ассоциации. В первом случае у студента роль "зачисленный", а во втором "учащийся". Группу можно считать сущностью-ассоциацией. Еще к этому есть инвариант: студент может учиться только в той группе, которая связана с факультетом в который он зачислен. Можно привести и другие примеры когда между сущностями могу существовать более чем одной ассоциации: между мужчиной и женщиной могут существовать две связи: муж и жена, начальник — подчиненный(встречал такое в жизни). Надеюсь понятно изложил.
Программа – это мысли спрессованные в код
Отредактировано 31.10.2024 22:19 Qulac . Предыдущая версия .
Re[4]: и еще один вопрос по реляционной структуре
От: paucity  
Дата: 01.11.24 00:26
Оценка:
Здравствуйте, Qulac, Вы писали:

Q>... могут существовать две связи: муж и жена, начальник — подчиненный


А если они в проекто-и/или-матричной организационной структуре имеют еще несколько связей: начальник — подчиненный;
подчиненный — начальник; ...; ...

Сколько FK надо запищнуть в одну таблицу?
Отредактировано 01.11.2024 0:27 paucity . Предыдущая версия .
Re[11]: и еще один вопрос по реляционной структуре
От: L_G Россия  
Дата: 01.11.24 09:27
Оценка: +1
PD>Вот только с UNION вопрос. Таблицы-то сильно разные. В них вообще может не быть одинаковых по смыслу полей, кроме ID, и то, если он в них есть(они могли бы использовать ID базовой как свой PK). Что брать-то ? И как потом определить, откуда взяли ?

Сорри, если не к месту вмешиваюсь и вообще уже поздно, но здесь я не понял — причём тут UNION, когда нужны просто два LEFT JOIN (или три для добавления в выборку данных по факультету в случае, когда студент в группе):
select * from students s --вместо звездочки - нужные поля, естественно, разные из groups и faculties.
  inner join facs_groups fg on s.fac_group_id=fg.id --джойн с базовой таблицей групп/факультетов
  left join faculties f on f.id=fg.id      --факультет; выбираемые поля f.*  будут NULL, если студент в группе
  left join groups g on g.id=fg.id         --группа; выбираемые поля g.*  будут NULL, если студент НЕ в группе
  left join faculties ff on g.fac_id=ff.id --факультет по группе; выбираемые поля ff.* будут NULL, если студент НЕ в группе
поля по факультету, чтобы не дублировать в выборке f.* и ff.*, логично выбирать через COALESCE(f.поле, ff.поле) AS поле

BTW, оставаясь в рамках ООП-идеологии, для исключения "лишней по Оккаму" базовой таблицы можно посчитать группу базовым классом, а факультет — его наследником, и в результате получится точно такая же структура данных, что и в решении с "псевдогруппами для студентов без группы" — т.е. "псевдогруппа" и "факультет как его предок, т.е. группа" — это по сути одна и та же сущность.

(И тогда вышеприведенный запрос упрощается с четырех JOIN до всего двух, а это явный выигрыш!)
Каша в голове — пища для ума (с)
Отредактировано 01.11.2024 10:18 L_G . Предыдущая версия . Еще …
Отредактировано 01.11.2024 9:32 L_G . Предыдущая версия .
Re: и еще один вопрос по реляционной структуре
От: Sinclair Россия https://github.com/evilguest/
Дата: 11.11.24 01:35
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>На императивном языке можно было бы ограничиться одной ссылкой на некий интерфейс или базовый класс. Если студент член группы, то на Group (а она на Faculty), если не член — прямо на Faculty. Может, и не лучшее решение, но возможное. А тут одним FK можно обойтись ?
Одним — нет, нельзя. Но можно получить гарантию непротиворечивости.
Первый FK — композитный, Student(GroupID, FacultyID) -> Group(ID, FacultyID)
Второй FK — простой, Student(FacultyID) -> Faculty(ID)
Первый предотвращает возможность попасть в группу с чужого факультета. Второй предотвращает возможность попасть на несуществующий факультет при пустой группе.
https://www.db-fiddle.com/f/4m6HA2zSzdKCE4bKSVwEtu/0
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[2]: и еще один вопрос по реляционной структуре
От: Pavel Dvorkin Россия  
Дата: 11.11.24 02:46
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Одним — нет, нельзя. Но можно получить гарантию непротиворечивости.

S>Первый FK — композитный, Student(GroupID, FacultyID) -> Group(ID, FacultyID)
S>Второй FK — простой, Student(FacultyID) -> Faculty(ID)
S>Первый предотвращает возможность попасть в группу с чужого факультета. Второй предотвращает возможность попасть на несуществующий факультет при пустой группе.

То есть когда студент становится студентом вне группы, Student.GroupID ставится в NULL ? А что тогда получится с первым FK ?
With best regards
Pavel Dvorkin
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.