Вставка внешнего ключа с несколькими значениями - PullRequest
3 голосов
/ 15 февраля 2012

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

Например:

Employee(id,name,skillid);
Skill(Skillid,skillname);

здесь экземпляр для Employee может быть

Employee(311,"john", (01,02) );
Skill (01,Java); Skill (02,C++);

Я реализовал тот же первичный ключ создания для таблицы, что и (is, skillid)

Но в случае, если у меня есть таблица:

create table Movie (Movie_ID varchar(5),                              
                            Cast varchar(5),
                            foreign key(Cast) references Person(Person_ID), 
                            primary key(movie_id, Cast));

и другая таблица:

create table Awards  (Award_Id varchar(5),
                                Person_Id varchar(5), 
                                Movie_Id varchar(5),
                                Award_Name  varchar(30),
                                Year number(4),
                                Organization_Id varchar(5),
                                primary key (Award_id,year,Organization_Id),
                                foreign key(Person_Id) references Person(Person_ID),
--                                foreign key(Movie_ID) references Movie(Movie_ID),
                                foreign key(Organization_Id) references Organization(Organization_Id));

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

Любые намеки, как это можно реализовать?

Ответы [ 3 ]

6 голосов
/ 15 февраля 2012

К сожалению, вы только что задали старый вопрос;

Как мне поместить две вещи в один столбец?

Ответ, конечно, нет;у вас есть две колонки.Чтобы расширить пример вашего сотрудника, ваша таблица сотрудников будет выглядеть следующим образом:

create table employees (
   id number
 , name varchar2(4000)
 , skill_1 number
 , skill_2 number
 , constraint employee_pk primary key (id)
 , constraint employee_skill_1_fs 
      foreign key ( skill_1 ) 
   references skills(skillid)
 , constraint employee_skill_2_fs 
      foreign key ( skill_2 ) 
   references skills(skillid) 
   );

Как вы можете видеть, это не очень приятная вещь и нарушает нормализацию;что произойдет, если вы хотите, чтобы у вашего сотрудника (или, конечно, вашего сотрудника) было 3 навыка?Или 10?

Вероятно, было бы лучше создать третью таблицу и выполнить все ваши объединения по одному первичному и внешнему ключу;так что вы бы

employees ( employee_id, ..., pk employee_id);
employee_skills ( employee_id, skill_id, ..., pk employee_id, skill_id, fk skill_id );
skills ( skill_id, description, ..., pk skill_id );
0 голосов
/ 15 февраля 2012

Если (movie,cast) является первичным ключом родительской таблицы, любая ссылочная таблица должна включать оба столбца во внешнем ключе. Это только правила.

Есть два способа решить эту проблему. Либо у вас неправильный первичный ключ, и в этом случае вам нужно изменить ограничение на таблицу MOVIES. В качестве альтернативы вам нужно добавить столбец CAST в таблицу AWARDS.

Композитные ключи - это боль в шее, когда дело доходит до внешних ключей. Вот почему многие практики предпочитают иметь суррогатный (или синтетический) первичный ключ, так что дочерние таблицы должны ссылаться только на один столбец. Оригинальный - составной - ключ все еще применяется, но как уникальный ключ.

0 голосов
/ 15 февраля 2012

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

CREATE TABLE car_type (
  make  VARCHAR2(100),
  model VARCHAR2(100),
  year  NUMBER,
  PRIMARY KEY pk_car_type( make, model, year )
);

тогда дочерняя таблица должна иметь все три столбца

CREATE TABLE car (
  vin   VARCHAR2(17) PRIMARY KEY,
  make  VARCHAR2(100),
  model VARCHAR2(100),
  year  NUMBER,
  FOREIGN KEY fk_car_car_type( make, model, year )
    REFERENCES car_type( make, model, year )
);

Использование нескольких столбцов в определениях внешнего ключа, как правило, становится болезненным, поскольку схемы становятся больше, и вам нужно объединять больше таблиц, поэтому люди вводят синтетические первичные ключи (то есть бессмысленные ключи, которые заполняются последовательностью). Это позволяет упростить вещи

CREATE TABLE car_type (
  car_type_id NUMBER PRIMARY KEY,
  make        VARCHAR2(100),
  model       VARCHAR2(100),
  year        NUMBER,
  UNIQUE uk_car_type( make, model, year )
);

CREATE TABLE car (
  vin   VARCHAR2(17) PRIMARY KEY,
  car_type_id NUMBER REFERENCES car_type( car_type_id )
);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...