Что делать, когда есть два Fk; s, и любой из них всегда равен нулю? - PullRequest
0 голосов
/ 06 мая 2019

У меня есть приложение, в котором есть тренеры, клиенты и тренировки. Один тренер может иметь много клиентов, а один клиент может иметь много тренеров = много ко многим

Один тренер может создать много тренировок, а одна тренировка может быть создана только одним тренером = один ко многим

Кроме того, один клиент может создать много тренировок, а одна тренировка может быть создана только одним клиентом = один ко многим

Моя проблема в том, что тренировки могут быть созданы только тренером или клиентом. Не оба. Каков наилучший способ структурировать таблицы и поля?

Прямо сейчас у меня есть тренировка с идентификатором: Pk, coachId: Fk, clientId: Fk. Но это означает, что значение coachId или clientId будет нулевым в каждой строке. Думаю, это не лучшая практика?

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

Текущий дизайн:

Coach   Client  Workout         CoachClient (composite)
id      id      id              coachId Fk
                coachId Fk      clientId Fk
                clientId Fk     

Ответы [ 2 ]

0 голосов
/ 07 мая 2019

Клиенты и Тренеры - Персоны.Таким образом, наличие одной таблицы решает вашу проблему с FK.

Однако, если существует много различий в столбцах «клиентов» и «тренеров», то это, вероятно, вызывает больше проблем, чем лечит.

Обратите внимание, что

  • Иностранные ключи имеют только небольшое количество свойств;вы просите больше, чем они могут дать.
  • Внешний ключ неявно создает индекс, чтобы повысить производительность;вы можете построить INDEX без FK.
  • Внешний ключ - это «ограничение», которое проверяется во время выполнения.Поскольку ваш сложный чек не может быть обработан ФК, может быть, вам следует отказаться от ФК?
0 голосов
/ 06 мая 2019

Вы находитесь на правильном пути, имея два отдельных FK (внешних ключа) в таблице workout.

Теперь, чтобы убедиться, что только один из FK всегда нулевой, а другой FK всегдаNOT null вы можете добавить ограничение:

create table workout (
  id int primary key not null,
  coach_id int,
  client_id int,
  constraint fk1 foreign key (coach_id) references coach (id),
  constraint fk2 foreign key (client_id) references client (id),
  constraint chk1 check (coach_id is null and client_id is not null 
                      or coach_id is not null and client_id is null)
);

Магия в последнем ограничении chk1.Он обеспечивает, что один и только один из них не равен нулю.

...