我意识到可能有类似的问题,但我找不到足够接近指导的问题。
鉴于此规范,
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',所以我认为这是另一件可以改变的事情。
*:“虚拟”外键,因为之前已经由高层决定,我们不应该使用实际外键
答案 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中,代理键强烈推荐。