代理键作为复合键上的外键

时间:2009-10-27 14:09:03

标签: sql database-design data-modeling composite-key surrogate-key

我意识到可能有类似的问题,但我找不到足够接近指导的问题。

鉴于此规范,

Site
---------------------------
SiteID      int    identity
Name        varchar(50)

Series
---------------------
SiteID      int
SeriesCode  varchar(6)
...
--SeriesCode will be unique for every unique SiteID

Episode
----------------------
SiteID      int
SeriesCode  varchar(6)
EpisodeCode varchar(10)
...

我提出的设计/实施是

Site
----------------------------
SiteID      int     identity
Name        varchar(50)


Series
-------------------------------------------
SeriesID    int     identity, surrogate key
SiteID      int         natural key
SeriesCode  varchar(6)  natural key
UNIQUE(SiteID, SeriesCode)
...

Episode
-------------------------------------------
EpisodeID   int     identity, surrogate key
SeriesID    int     foreign key
EpisodeCode varchar(6)  natural key
...

这有什么问题吗?可以将SeriesID代理作为外来*密钥吗?我不确定我是否遗漏了可能出现的任何明显问题。或者使用复合自然键(SiteID + SeriesCode / SiteID + EpisodeCode)会更好吗?本质上,它将Episode表与Series表分离,并不适合我。

值得补充的是,SeriesCode在填充这些表的原始输入数据中看起来像'ABCD-1'和EpisodeCode就像'ABCD-1NMO9',所以我认为这是另一件可以改变的事情。

*:“虚拟”外键,因为之前已经由高层决定,我们不应该使用实际外键

3 个答案:

答案 0 :(得分:4)

是的,一切都很好。我可能做的唯一(次要)观点是,除非你有另一个第4个子表挂在Episode上,否则你可能不需要EpisodeId,因为Episode.EpisodeCode是一个足以在Episode中识别和定位行的单个属性自然键。当然,将它留在那里并没有什么坏处,但作为一般规则,我添加代理键作为子表中FK的目标,并尝试在每个表中添加一个叙述键来识别和控制冗余数据行......因此,如果一个表没有其他表引用它的FK,(并且永远不会)我有时不会在其中包含代理键。

答案 1 :(得分:1)

什么是“虚拟”外键?上级决定不使用外键约束吗?在这种情况下,您根本不使用外键。你只是假装。

并且Episode是实体的最佳选择吗?难道它不是真的意味着Show或Podcast左右,而且恰好一直是系列剧的一部分吗?如果是这样,将来会改变吗? Will Episode最终会被滥用来包含Show in a Series?在这种情况下,通过系列连接剧集可能会回来困扰你。

考虑到这一切,并假设你作为一个咕噜声可能无法改变任何一个:如果我是你,我会尽可能使用自然键感觉更安全。在没有外键约束的情况下,它可以更容易地识别坏数据,如果你以后必须使用一些SeriesCode ='EMPTY'技巧,那么使用自然键也会更容易。

答案 2 :(得分:0)

我的建议:

尽可能使用自然/商家作为主键,但以下3种情况除外:

  1. 插入
  2. 时,自然/商家密钥未知
  3. 自然/商业密钥不好(它不是唯一的,它可能经常更改)
  4. 自然/商家密钥是超过3列的组合,该表将包含子表
  5. 在情况1和2中,代理键需要

    在情况3中,代理键强烈推荐