【问题标题】:ER model: when to add a relationship and when not to addER 模型:何时添加关系,何时不添加
【发布时间】:2016-01-25 02:15:15
【问题描述】:

考虑一下这个 ER 设计示例。我有三个实体:

  1. 歌手
  2. 专辑
  3. 歌曲

每位歌手至少有一张专辑(根据定义),每张专辑至少有一首歌曲。每首歌只属于一张专辑。所以我也有两个关系:

  1. 专辑:歌手 (1-or-more:exactly-1)
  2. song:album (1-or-more:exactly-1)

如果我想知道谁在唱这首歌,我可以加入以专辑实体为轴心的表格。

现在我的问题是:我是否应该添加歌手和歌曲之间的直接关系?我不明白它是否仅取决于用例,或者是否有严格的规则/最佳实践。如果我添加它,我会使用更多的磁盘空间,但我需要更少的内存来查询歌曲作者(我不需要连接)。

解决办法是什么?

【问题讨论】:

  • 对不起,我犯了一个错误。问题已更新!
  • 第 1 步:不要担心磁盘空间是首要问题 - 首先为域找到合适的模型,然后您可以考虑对空间/时间的影响和决定是否需要调整模型。另外:您的专辑和歌曲之间的一对多关系将不支持包含以前发布的歌曲的“最热门”专辑(当然,除非您的域要求歌曲是单张专辑独有的)
  • 谢谢!您对“最热门歌曲”的警告是正确的。我简化了建模以将问题集中在主要主题上:是否有(拇指)规则/最佳实践来决定是否添加关系?
  • @philipxy 感谢您的纠正,我改变了问题中关系的基数。

标签: database-design entity-relationship


【解决方案1】:

(我假设专辑:歌手和歌曲:专辑实际上都是 1-or-more:exactly-1,因为您的“一对多”与您的其他描述相矛盾。)

关于 2 个表格是正确的:您不应该同时使用这三个表格。 SingerSong 总是等于 (SingerAlbum JOIN SongAlbum) PROJECTed on SINGER & SONG。使用全部 3 个是多余的,因为当两表设计只涉及一个时,需要更新多个表,并且需要多表约束来强制 SingerSong 和其他表之间的一致性。

重新设计表格:每张表格都有一个意义/谓词,每一个存在的行和每一个不存在的行(适合它)都构成一个陈述/命题。我们选择足够的含义/谓词来描述所有可能出现的情况。 (参见this re bases 和this re 查询以及我使用“谓词”的其他答案。)“冗余”是指两行同时做出重叠的陈述/命题。然后我们必须更改多行,而在另一种设计中我们只能更改一个。 (或更多与更少。)我们只需要了解我们选择的含义/谓词所说的内容。遗憾的是,大多数信息建模方法和产品都没有解决关系/关系的含义/谓词,即使它们是建模的基础和实体-关系和关系模型中术语的来源。 规范化解决了某些冗余,这些冗余可以通过在 AND 处拆分来从含义/谓词中消除。 (因此将其关联的表/关系替换为其他人的 JOIN)。

需要 3 个表: 这里有谓词“歌手 SINGER 制作专辑 ALBUM”、“歌曲 SONG 在专辑 ALBUM”和“歌手 SINGER 演唱歌曲 SONG”。我们不能直接用前两个来表达第三个。但由于第三个谓词在您的特定应用程序中第一个加上第二个隐含,因此您不需要它。即“歌手 SINGER 演唱歌曲 SONG”在您的应用程序中恰好是“对于某些 ALBUM,歌手 SINGER 制作了专辑 ALBUM 并且歌曲 SONG 在专辑 ALBUM 中”。 (即谓词满足 (SingerAlbum JOIN songAlbum) PROJECTed on SINGER & SONG 中的行。)但是,如果说多个歌手可能在一张专辑中,而不是同时演唱所有歌曲,或者如果说有歌曲被唱但不在专辑中,那么前两个并不暗示第三个,因此您既无法表达也无法从其他行中推断出第三个中的行。 (请注意您添加“至少一个”/“仅一个”如何使谓词和约束复杂化并导致冗余设计,即使您认为您“简化了建模以将问题集中在主要主题上”。

重新优化:始终首先产生最直接的设计。在您拥有更多设计和查询经验以了解相关因素之前,您不应该担心存储和时间权衡。然后您应该使用估计和测量来证明更改的合理性。

【讨论】:

  • 好吧,如果我理解正确你的答案,如果我的模型中的其他地方有相同的信息(例如,加入 + 投影),我不应该使用关系。正确的? :)
  • 是的,这是一般的想法。请参阅我的编辑。请注意,如果您不涉及某些子句(例如“恰好一个”),您需要 3 个表,因为“相同信息”不会出现。 PS 最好不要谈论(“更多”或“更少”)“信息”。只需谈论数据库或(基本变量或查询结果)表或(存在或不存在)行“状态”/“断言”。 (由于哪些行在哪些表中。)
  • 最后一点 +1 - 总是先让它工作,然后只有在你发现速度或空间是一个问题时才优化。
【解决方案2】:

编辑:我刚刚意识到,每张专辑只有一位歌手。在这种情况下,您有三个关系:

  • 歌手专辑
  • 歌曲专辑
  • 歌手歌曲

您的理解是正确的 - 您可以选择同时使用这三个,以获得更多的磁盘使用率但更快的查询。或者,您可以只选择两个,以减少磁盘使用量和降低查询速度。

这始终取决于具体情况 - 如果您知道可以用两个表表示关系而不会丢失数据,那么您可以在速度和大小之间做出选择。但是,要考虑的一个重要因素是未来的证明。例如,将来您可能希望每张专辑拥有不止一位歌手。那么就不再隐含哪个歌手唱哪首歌了。综合考虑,它一个数据库,所以你通常期望它又大又快。

【讨论】:

  • 谢谢安德鲁。所以在这种情况下,ER 理论并不建议最佳实践,不是吗?
  • 不记得了。但是@philipxy 对冗余提出了一个很好的观点——通常,您让数据库强制执行约束,因此很难使数据库进入不一致的状态。但是,当您有冗余数据时,很容易输入相互矛盾的值。当一个表相当于另外两个表的连接时,设置数据库来强制一致性并不容易。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-20
  • 2016-10-29
  • 1970-01-01
  • 2021-10-13
  • 1970-01-01
相关资源
最近更新 更多