我是否需要一对多关系中的代理键?

时间:2009-07-13 07:13:06

标签: sql database-design

create table A (
    id int(10) not null, 
    val1 varchar(255), 
    primary key (id)
);

方法[a]:

create table B (
    a_id int(10) not null, 
    val2 varchar(255), 

    foreign key (a_id) references A(id)
);

方法[b]:

create table B (
    id int(10) not null, 
    a_id int(10) not null, 
    val2 varchar(255), 

    foreign key (a_id) references A(id), 
    primary key (id)
);

通过选择[a],我可以避免在表'B'中创建“id”代理键。从建模的角度来看,创建表'B'的首选方法是什么?

3 个答案:

答案 0 :(得分:4)

你从不需要一个代理键(因此它的名字)。看起来你正在混合逻辑模型和物理模型。对于你的逻辑模型,你可能会有

CREATE TABLE A (
    Val1 varchar() not null,
    constraint PK_A KEY (Val1) --?
)

CREATE TABLE B (
    Val1 varchar() not null,
    Val2 varchar() not null,
    constraint PK_B KEY (Val2), --? or Val1,Val2?
    constraint FK_A FOREIGN KEY (Val1) references A
)

(上面的化妆SQL,但希望你明白这一点)

现在,对于物理模型,您可以在任何有意义的地方引入代理 - 逻辑键很长(例如varchars)。但无论你做与否,都取决于你。并记住仍然强制执行逻辑键

答案 1 :(得分:1)

对于一般的代理键,

我的计算机科学课程的一位教授说“不”。

对我来说,实际经验说,是的。

我宁愿使用一个,尽管只是为了便于阅读SQL语句而增加空间,并且在需求更改时更灵活。

答案 2 :(得分:0)

据我理解:在[a]中,你创造的是1:1的关系,在[b]你不是。 他们不是替代品!

如果[b],如果表A将持有发票,则表B可用于发票,而在[a]中则不能,因为表A中的每条记录只能有一条记录。(因此只有1条发票每张发票)

所以,如果你真的想要答案,使用[b],你的[a]构造只能用一个表替换,可能不是你的意思。 (也因为你没有设置主键,与1:1关系中的FK相同)