SQL中的外键问题

时间:2011-02-17 13:43:26

标签: sql foreign-keys

我只是想问一下,因为我创建了一个带有两个主键的列的表,如下所示:

CREATE TABLE Parent(
Mother varchar(50) NOT NULL,
Father varchar(50) NOT NULL,
PRIMARY KEY(Mother, Father),
Organization varchar(50) NOT NULL
);

然后我试图创建另一个表,它将具有上面显示的表的外键:

CREATE TABLE Child(
Name varchar(50) NOT NULL PRIMARY KEY,
Child_Mother varchar(50) REFERENCES Parent(Mother),
Child_Father varchar(50) REFERENCES Parent(Father),
Sibling varchar(50) NOT NULL
);

所以我基本上试图将子表上的两列引用到父表中的一个列,其中包含两个主键。这甚至可能吗?非常感谢你! :)

*仅限样本表。但实际情况与此相似。

3 个答案:

答案 0 :(得分:4)

您尚未创建“包含两个主键的列的表”,您已使用单个复合主键创建了一个。

你正在做的事情确实是可能的,但不是你做的那样。

问题是,您可以有两个Parent行具有相同的Mother和不同的Father。但是Child_Mother上的外键关系将需要Mother表中的{em>单个 Parent实例,否则它将不知道它所指的是哪一行。< / p>

您可以在子项中使用组合列来引用组合的主键,也可以将Parent行分开。

通过这个,我的意思是父表通常不会将两个人放在一行中,通常每人有一行,而孩子只会引用Parent表中的两个单独的行,一个为母亲和一对父亲。


就您的实际表而言:

create table Subject(
    Subject_ID varchar(50) NOT NULL,
    Subject_Description varchar(50) NOT NULL,
    PRIMARY KEY(Subject_ID, Subject_Description),
    Subject_SID int references Student(Student_ID),
    Unit varchar(50) NOT NULL
)

这实际上没有标准化,因为主题描述几乎不变取决于主题ID。我认为主键应该只是主题ID。无论如何都要在主题描述上有另一个索引,但它不应该是主键的一部分。

我仍然不确定你明白我在说什么,所以我会试着澄清一下。这一行:

PRIMARY KEY(Subject_ID, Subject_Description)

制作两个主键,它使单个主键由两列(id和description)组成。因此,如果描述不同,则可以使用两个具有相同ID的行。

因此,对ID列的外键引用不可能。假设你有两行:

ID  Subject  Other
--  -------  ---------
 7  Maths    blah blah
 7  Physics  yada yada

然后尝试将Schedule_SID设置为7的行添加到计划表中。这会阻塞,因为DBMS不会知道您指的是哪个 7。所以它甚至不应该让你设置那个外键约束,因为目标列不是唯一的。

答案 1 :(得分:1)

试试这个 -

CREATE TABLE Child(
    Name varchar(50) NOT NULL PRIMARY KEY,
    Child_Mother varchar(50),
    Child_Father varchar(50),
    Sibling varchar(50) NOT NULL,
    Foreign Key (Child_Mother, Child_Father) references Parent(Mother, Father)
);

由于您要创建一个由两列组成的主键,因此您需要一起引用它们。

paxdiablo说的是真的。您正在创建一个由两列组成的复合主键。我建议你使用Surrogate Primary Key

修改

CREATE TABLE Child(
    id bigint NOT NULL auto_increment,  // an "id" column
    Name varchar(50) NOT NULL unique,
    age int not null,
    primary key (id)    // "id" column is being declared as surrogate primary key
);

第二次修改

create table Subject(

    id int not null,
    Subject_ID varchar(50) NOT NULL,
    Subject_Description varchar(50) NOT NULL,
    PRIMARY KEY(id),
    Subject_SID int references Student(Student_ID),
    Unit varchar(50) NOT NULL
);

ALTER TABLE Subject ADD CONSTRAINT subject_unique UNIQUE (Subject_id, Subject_Description);

create table Schedule(
    Day_MTWTHF varchar(50) NOT NULL,
    TIME_HH varchar(50) NOT NULL,
    subject_id int not null,                   -- my newly added column
    Schedule_SID int references Student(Student_ID),
    foreign key(subject_id) references Subject(id)
);

答案 2 :(得分:-1)

我会说您选择的主键对于父表来说很差。看起来你正在使用名字。如果你有两个名字匹配的独立夫妻会怎么样?约翰&amp;根据你的设计,简·史密斯和爱丽丝和鲍勃的孩子们也将是同一个约翰&amp;来自下一个城镇的简·史密斯(Jane Smith)为孩子们准备了查理(Charlie)和多洛雷斯(Dolores),尽管实际上他们完全不相关。

名称总是键的错误选择,因为名称可以重复。使用保证唯一的东西,例如自动递增的整数,会更加安全,并且可以让你从斯普林菲尔德的J&amp; J Smith与Shelbyville的J&amp; J Smith分开。