2010-05-02 51 views
1

我有以下结构的三级数据库(简化,只显示主键):为表C中三级数据库 - 外键

Table A: a_id 
Table B: a_id, b_id 
Table C: a_id, b_id, c_id 

所以可能的值会是这样的:

a_id b_id c_id 
    1  1  1 
    1  1  2 
    1  1  3 
    1  2  1 
    1  2  2 
    2  1  1 
    2  2  1 
    2  2  2 
... 

我现在不确定,应该如何设置外键;或者它们是否应该设置为主键。我的想法是在表B B.a_id -> A.a_id上有一个外键,在C C.a_id -> A.a_id(C.a_id, C.b_id) -> (B.a_id, B.b_id)上有两个外键。

这是我应该设置外键的方式吗?是否需要C->A的外键?或者我甚至需要外键,因为所有这些列都是主键的一部分?

谢谢。

回答

1

如果你已经有表B和表A之间的外键,以确保表B中只包含有一个价值a_id存在于表A中的条目,那么表C和表A之间的额外FK上a_id是不必要。当然,这需要表B和表A之间的FK关系以任何方式被嵌入,激活并且不被禁用或规避。

使表C和表B之间的FK链接已经保证TableC.a_id只能引用一个有效值a_id(因为它通过表B和表A之间的FK关系在表B中得到保证)。

+0

啊,所以我不需要外键来表达不同表的实际关系,而只是为了保持完整性? – poke 2010-05-02 20:45:35

3

首先,外键对于在父表中声明记录的存在是必要的,而主键则用表来声明记录的唯一性。所以你需要两个。

一般来说,你想避免有复合主键。所以,你的表应该是这样的:

表A:A_ID(PK)
表B:B_ID(PK),A_ID(FK)
表C:C_ID(PK),B_ID(FK)

你不需要表C和表A之间的外键,因为这关系是由表C和表B,表B和表A.

之间

编辑外键暗示

使用复合主键 有什么不好?

将表C连接到表B时,可以减少一行类型。此外,在传播外键时累积列数,因此表D将具有四列的复合主键。在某个时候,这开始变得愚蠢。我曾经在一个有J表的系统上工作,其中主键列和两个数据列分别为九个

另一件事情是,复合键也可以与商业密钥相关联。将这些传播为外键可能是一个真正的脖子痛。一旦我们决定为一个表使用代理(合成)键 - 自动增量,序列,guid,无论如何 - 一致性表明我们应该在我们所有的表上使用相同的主键的机制。

有一些ORM工具,这使得它很难使用复合键。我不提供,作为一个很好的理由不使用复合键,因为我强烈反对的ORM工具的驾驶我的数据模型的局限性,我只是指出来。

在另一方面可存在于使用化合物键的优点。我曾在一个系统上,我们不得不做大量的格式

select D.* 
from D 
    join A on (D.a_id = A.id) 
where A.some_col = 'whatever' 

不必加入表d表C表B去表A是一个明确的福音的查询。当他必须限制对我们所有表格的访问时,这将更加真实,因为用户可以访问表A的子集。

因此,它不是一个硬性和快速规则。两方面的观点都让人们对此深有感触。在我的职业生涯中,我都强烈支持复合主键,但现在我发现自己通常下来赞成单列主键,与唯一约束在适当的时候实施复合业务键。

总之,化合物主键不只是笨重。单列,代理主键可能是行业标准。但是,在某些情况下,复合主键是正确的选择。

+0

使用复合主键有什么不好?我有对于从1开始在B/C比对于连续indentifier每个新块整数索引更多的使用。 – poke 2010-05-02 20:39:05

+0

要难得多。 – Randy 2010-05-02 20:55:43

+0

非常感谢您的编辑。我将只有这三个级别,分开的关键数字在这个项目中肯定会有所帮助,但我会在下一个项目中记住你的观点。再次感谢! – poke 2010-05-03 15:49:08