如果两个表具有“一对一”关系,它们是否应与主键具有相同的列?

时间:2012-06-23 11:20:07

标签: sql

假设我有一个名为Users的表,它代表网站的注册用户。我还有一个AccountActivation表,用于存储发送给新用户电子邮件的随机生成的字符串,以验证该电子邮件。

AccountActivation表有UserId列,它也恰好是Users表的主键。它还有ActivationCode列来存储代码。任何一列都可以唯一标识AccountActivation表中的行。

因此,如果我选择激活码列作为主键,我最终会得到两个具有不同主键的一对一表。我认为在一对一的关系中,两个表必须具有相同的主键?

4 个答案:

答案 0 :(得分:1)

如果选择ActivationCode作为PK,那么为什么你有两个一对一的关系?

唯一的关系是

AccountActivation.UserId -> Users.UserId

或者你认为你突然有什么?

如果按照您的建议进行操作,那么表Users的PK就在UserId上,而表AccountActivation的PK就在ActivationCode上 - 根本不是问题,并且没有理由不以这种方式这样做。

您为UserId的PK选择哪一列(ActivationCodeAccountActivation)并不重要 - 这不会影响/干扰AccountActivation之间的FK关系和User,也没有增加任何一种额外的一对一关系......

如果您为ActivationCode的PK选择AccountActivation,我将采取的唯一额外步骤是在UserId上创建非聚集索引,以便加入这两个表的查询将受益于最高性能。

答案 1 :(得分:1)

如果只有一个ActivationCode,他们可以共享UserId。但这意味着当用户重新生成密钥时,您应该更新旧行或删除它。

但为什么你需要存储这样的数据?您还可以使用User中的唯一数据将帐户激活码与某种计算和加密进行合成。

只是为了说明我的建议:

Users table has two columns UserId CreationDate

然后令牌可能是UserId + CreationDate(示例)。您可以在没有数据库中的额外数据的情况下生成并检查它。我知道这可能不符合您的要求。

答案 2 :(得分:1)

使AccountActivation中的UserId列成为Users表的外键。

Users
=====

UserId primary key
Name
Address
etc...

AccountActivation 
=================

UserId primary key (foreign key to Users.UserId)
ActivationCode (unique constraint)

现在你有一对一的关系

答案 3 :(得分:1)

您不需要在2个表中使用与主键相同的列来建立一对一的关系 您可以在AccountActivation表中将任何列作为主键。

UserId AccountActivation表的外键是Users表中的主键。因此,您绝对应该能够使用此列从AccountActivation表中唯一标识用户激活码,无论它是否是该表的主键(但它应该是唯一的,我希望它会这样)。