0

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

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

现在假设我有第二张桌子:

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

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

 _______________________
|   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) 参考 DocumentVersion
  • FK(userId) 参考用户

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

4

1 回答 1

0

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

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

于 2012-12-10T19:20:27.840 回答