2012-02-14 70 views
2

我想知道,是否有任何可能性來創建一個表,我有一個表接受外鍵,但可能有同一行的多個值。插入一個具有多個值的外鍵

例如:

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

這裏員工的一個實例可能是

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

我實現了表一樣使主鍵(是,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作爲一個外鍵,因爲它引用的表有兩件事情作爲其主鍵的組合。而且我不使用獎勵表中的那些屬性的第二個。

任何提示如何實現?

+0

爲什麼'Cast'在'Movie'的主鍵中? – Neil 2012-02-14 21:23:52

回答

5

不幸的是,您剛剛提出了一個古老的問題;

如何在一列中放入兩件東西?

答案當然是,你沒有;你有兩列。爲了延長您的員工例如你的員工表將成爲:

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

我是否需要使用外鍵約束在employee_skills(employee_id,skill_id,...,pk employee_id,skill_id)中指定; – typedef1 2012-02-14 21:46:59

+0

@ typedef1,對不起,我忘了fk; employee_skills會有一個employee_id,skill_id和skill_id的技能。 – Ben 2012-02-14 21:52:35

+0

我認爲它也會有employee_id作爲fk呢? – typedef1 2012-02-15 00:45:43

0

如果你想在父表中創建一個複合主鍵,你需要在子表中創建一個複合外鍵。換句話說,如果你想父表使用由三個不同的列

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) 
); 
0

如果(movie,cast)是父表的任何引用表必須包括外鍵都列的主鍵。這只是規則。

有兩種方法可以解決這個問題。要麼你的主鍵錯了,在這種情況下,你需要修改MOVIES表的約束。或者,您需要將CAST列添加到AWARDS表。

當涉及到外鍵時,複合鍵是頸部疼痛。這就是爲什麼許多從業者喜歡擁有代理(或合成)主鍵,以便子表只需引用單個列。原始複合密鑰仍然是強制執行的,但作爲唯一的密鑰。