每个表都应该有一个主键吗?

时间:2011-08-15 12:57:35

标签: sql database

我读到某处说每个表都应该有一个主键来实现1NF。

我有一个tbl_friendship表。

表格中有两个字段:所有者和朋友。

所有者和朋友的字段是tbl_user中自动增量id字段的外键。

这个tbl_friendship是否有主键? 我应该在tbl_friendship中创建一个自动增量id字段并将其作为主键吗?

7 个答案:

答案 0 :(得分:6)

主键可以应用于多个列!在您的示例中,主键应位于两列上,例如(Owner,Friend)。特别是当所有者和朋友是用户表的外键而不是实际名称时(个人而言,我的身份列使用“Id”命名约定,因此我会(OwnerId,FriendId)

我个人认为每张桌子都应该有一把主键,但你会发现其他人不同意。

这是我写的关于普通形式主题的文章。 http://michaeljswart.com/2011/01/ridiculously-unnormalized-database-schemas-part-zero/

答案 1 :(得分:4)

是的,每个表都应该有一个主键。

是的,你应该创建代理键..也就是一个自动增量pk字段。

你还应该将“朋友”作为自动增量字段的FK。


如果您认为将来要“重新加密”,您可能需要考虑使用自然键,这些字段可以自然地识别您的数据。关键是,编码始终使用自然标识符,然后在这些自然键上创建唯一索引。将来,如果你必须重新密钥,你可以,因为你的ux保证你的数据是一致的。

如果您必须这样做,我只会这样做,因为它会增加您的代码和数据模型的复杂性。

答案 2 :(得分:3)

从您的描述中不清楚,但是所有者和朋友外键并且任何给定对之间只能存在一种关系?这使得两个外键列成为自然主键的完美候选者。

另一种选择是使用代理键(如您所建议的额外自动增量列)。看一下here进行深入讨论。

答案 3 :(得分:2)

主键也可以是抽象的。在这种情况下,每个元组(所有者,朋友),例如, (“戴夫”,“马特”)可以形成一个独特的条目,因此是你的主要关键。在这种情况下,不使用名称,而是使用引用另一个表的键是有用的。如果您保证,这些元组不能有重复项,则您有一个有效的主键。

出于处理原因,引入一个特殊的主键可能很有用,例如自动增量字段(例如在MySQL中)或使用Oracle的序列。

答案 4 :(得分:1)

为了遵守1NF(对于定义1NF的内容并不完全同意),是的,您应该在每个表上标识一个主键。这对于提供每条记录的唯一性是必要的。

http://en.wikipedia.org/wiki/First_normal_form

通常,您可以通过多种方式创建主键,其中一个是具有自动增量列,另一个是具有GUID的列,另一个是具有两个或更多个将标识行的列在一起时是独一无二的。

答案 5 :(得分:0)

如果主表有主键,那么从长远来看,您的表格将更容易管理。至少,您需要唯一标识表中的每条记录。用于唯一标识每条记录的字段也可能是主键。

答案 6 :(得分:0)

是的,每张桌子都应该有(至少一个)钥匙。由于许多原因,不希望在任何表中复制行,因此将约束放在这两列上。