复合键中的外键

时间:2012-12-10 18:58:51

标签: sql relational-algebra

假设我有一个表,Document,看起来像这样:

 _______________________
|        Document       |
|-----------------------|
| DocumentId int PK     |
| (add't fields)        |
|_______________________|

现在假设我有第二张表:

 _______________________
|    DocumentVersion    |
|-----------------------|
| DocumentId int PK, FK |
| VersionId int PK      |
| (add't fields)        |
|_______________________|

最后,假设我希望创建一个引用DocumentVersion的第三个表,可能是对已访问每个版本的用户进行审计(假设存在用户表):

 _______________________
|   VersionAccessLog    |
|-----------------------|
| DocumentId int PK, FK |
| VersionId int PK, FK  |
| UserId int PK, FK     |
| AccessTime DateTime PK|
|_______________________|

也许不是最好的例子,但希望足以说明我的问题。

关注 VersionAccessLog ,我们有:

  • PK(DocumentId,VersionId,UserId,AccessTime)
  • FK(DocumentId,VersionId)REFERENCES DocumentVersion
  • FK(userId)REFERENCES User

现在我的问题是,我是否也应该在VersionAccessLog中创建 FK(DocumentId)?乍一看,密钥似乎是多余的 - FK对DocumentVersion强制执行引用完整性。但是,从关系代数的角度来看,是否存在此密钥?从实际角度来看(如果需要,假设是SQL Server 2012),是否包含或排除密钥有任何性能影响?

1 个答案:

答案 0 :(得分:0)

包含附加密钥会对性能产生影响,因为数据库将检查每个插入(子)或删除(父)上的FK。从实际角度来看,我通常不包括额外的密钥,因为验证中确实没有任何价值,并且有轻微的性能成本。

我确保如果模式被更改并且DocumentVersion和VersionAccessLog之间的FK被删除,则在VersionAccessLog和Document之间添加FK。我可以看到添加它的唯一另一个时间是,如果使用了一些Schema感知的DAO库,它反转了来自FK的Has-a关系,并且值得包括它。