2

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

鉴于此规范,

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”,所以我想这是可以改变的另一件事。

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

4

3 回答 3

4

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

于 2009-10-27T14:18:20.583 回答
1

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

剧集是实体的最佳选择吗?这不是真的意味着 Show 或 Podcast 之类的吗,而且现在恰好总是一个系列的一部分?如果是这样,将来会改变吗?剧集最终会被滥用以包含系列之外的节目吗?在这种情况下,通过 Series 将 Episode 与 Site 联系起来可能会再次困扰您。

鉴于这一切,并假设您作为 grunt 可能无法更改任何内容:如果我是您,我会尽可能使用自然键更安全。在没有外键约束的情况下,它可以更容易地识别坏数据,如果你以后不得不求助于一些 SeriesCode='EMPTY' 技巧,使用自然键也更容易。

于 2009-10-27T16:09:30.453 回答
0

我的建议:

尽可能使用natural/business 作为主键,以下 3 种情况除外:

  1. 插入时自然/业务密钥未知
  2. 自然/业务密钥不好(它不是唯一的,很容易经常更改)
  3. 自然/业务键是超过 3 列的组合,并且该表将具有子表

在情况 1 和 2 中,需要代理键。

在情况 3 中,强烈建议使用代理键。

于 2012-08-24T20:13:11.953 回答