Внешний ключ таблицы ассоциаций - PullRequest
0 голосов
/ 20 февраля 2019

Можно ли использовать ссылку на таблицу сопоставления «многие ко многим» или лучше использовать явные ФК?

Давайте предположим, что у нас есть некоторая модель «многие ко многим», подобная этой:

CREATE TABLE Project (
  id int NOT NULL,
  ....
  PRIMARY KEY(id)
);
CREATE TABLE Programmer (
  id int NOT NULL,
  ....
  PRIMARY KEY(id)
);
CREATE TABLE Project_Programmer_Association(
  id int NOT NULL,
  project_id int,
  programmer_id int,
  .... (probably some other data)
  FOREIGN KEY (project_id) REFERENCES Project (id),
  FOREIGN KEY (programmer_id) REFERENCES Programmer(id)
);
CREATE TABLE Task (
  id int NOT NULL,
  project_programmer_id int,
  ....
  PRIMARY KEY(id),
  FOREIGN KEY (project_programmer_id) REFERENCES Project_Programmer_Association(id)
);

В таблицах Project и Programmer есть некоторые данные, необходимые для Задачи, поэтому мне нужны ссылки на обе таблицы.У меня вопрос: стоит ли использовать эту ссылку в Задании

CREATE TABLE Task (
  id int NOT NULL,
  project_programmer_id int,
  ....
  PRIMARY KEY(id),
  FOREIGN KEY (project_programmer_id) REFERENCES Project_Programmer_Association(id)
);

, иначе лучше использовать два явных ключа (исключая отсутствие дополнительного объединения)

CREATE TABLE Task (
  id int NOT NULL,
  project_id int,
  programmer_id int,
  ....
  PRIMARY KEY(id),
  FOREIGN KEY (project_id) REFERENCES Project (id),
  FOREIGN KEY (programmer_id) REFERENCES Programmer(id)
);

Ответы [ 2 ]

0 голосов
/ 21 февраля 2019

Я бы предпочел следующую схему:

CREATE TABLE Project (
  id int NOT NULL,
  ....
  PRIMARY KEY(id)
);
CREATE TABLE Programmer (
  id int NOT NULL,
  ....
  PRIMARY KEY(id)
);
CREATE TABLE Project_Programmer_Association(
  project_id int,
  programmer_id int,
  PRIMARY KEY(project_id, programmer_id),
  FOREIGN KEY (project_id) REFERENCES Project,
  FOREIGN KEY (programmer_id) REFERENCES Programmer
);
CREATE TABLE Task (
  id int NOT NULL,
  project_id int,
  programmer_id int,
  PRIMARY KEY(id),
  FOREIGN KEY (project_id, programmer_id) REFERENCES Project_Programmer_Association
);

, поскольку она имеет следующие преимущества: нет ненужного ключа для Project_Programmer_Association, ссылочная целостность гарантирована для Task;возможность соединения напрямую Tasks с Project_Programmer_Association, Project и Programmer.Обратите внимание, что в случае, если для каждой пары программист-проект существует только задача (и только в этом случае), вы также можете удалить id из Задачи и сделать первичный ключ двумя другими атрибутами.

0 голосов
/ 20 февраля 2019

Правильный вопрос не «что лучше», а «который представляет ваши данные».

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

Если бы он мог содержать данные, и, более конкретно, если проект и программист могут иметь несколько ассоциаций (например, Боб является ведущим разработчикомв проекте X, но только в качестве консультанта в проекте Y), вам определенно необходим внешний ключ для самой ассоциации, чтобы правильно представить вашу модель данных.

...