0

我正在尝试为艺术家和歌曲建模,但我有一个问题,我有一个 Song_Performance 可以由许多艺术家表演(比如二重唱),所以我有一个 Artist_Group 来代表歌曲的演唱者。

好吧,我现在在 Artist 和 Artist_Group 之间建立了多对多的关系,其中 Artist_Group 由该组中的艺术家集合唯一标识。我可以创建一个交集实体,表示艺术家参与 Artist_Group (Artist_Group_Participation?)

我无法想出如何为 Artist_Group 实体提供一个主键,该主键保留了同一组艺术家代表同一组的事实,并且缺少 Artist_Group 实体的主键意味着我缺少一个Artist_Group_Participation 实体的外键。

John Carlis 和 Joseph Maguire 的“Mastering Data Modeling”一书提到了这种形状并将其称为“Many-Many Collection Entity”,并指出它非常罕见,但没有说明如何解决它,因为显然很多一对多关系不能直接存储在 RDBMS 中。我该如何代表这个?

编辑:

看起来每个人都在建议一个交叉表,但这不是我的问题。我有这个。我的问题是强制执行约束,即您不能添加 Artist_Group 条目,其中包含的艺术家组与现有组相同,忽略顺序。我想过让 Artist_Group 的 ID 是一个 varchar,它是组成它的各种艺术家的串联,如果顺序很重要,这将解决问题,但是为“Elton John and Billy Joel”设置一个 Artist_Group 并不能阻止添加“比利·乔尔和埃尔顿·约翰”的组合。

4

5 回答 5

1

Artist 和 Artist_Group 的主键都是数字增量 ID。然后你会有一个 Artist_Group_Participation 表,它有两列:artist_id 和 group_id。这些将是引用其各自表的 ID 的外键。然后选择您将使用 JOIN 的所有内容。

编辑:对不起,我误解了你的问题。我能想到的唯一其他方法是在 Artist_Group 表中添加一个“艺术家”列,其中包含艺术家及其 ID 的序列化数组(假设您使用的是 PHP,但其他语言有等价物)。然后只需向该列添加一个 UNIQUE 约束。

于 2009-05-10T04:55:52.327 回答
1

您可以使每个艺术家的 ID 对应于位域中的位。因此,如果 Elton John 的 ID 为 12,Billy Joel 的 ID 为 123,则由 Elton John 和 Billy Joel 之间的二重唱形成的“组”为Artist_GroupID 10633823966279326983230456482242760704(即,它具有第 12 位和第 123 位设置)。

您可以使用交集表强制关系。例如,CHECK在 PostgreSQL 中使用约束:

CREATE TABLE Artist_Group_Participation (
  artist_id int not null,
  artist_group_id int not null,
  PRIMARY KEY (artist_id, artist_group_id),
  FOREIGN KEY (artist_id) REFERENCES Artists (artist_id),
  FOREIGN KEY (artist_group_id) REFERENCES Artist_Group (artist_group_id),
  CHECK (B'1'<<artist_id & artist_group_id <> 0)
);

诚然,这是一个 hack。Artist_Group当代理键应该是唯一的但不包含信息时,它对代理键施加了额外的重要性。

此外,如果您有成千上万的艺术家,并且每天都有新的艺术家,事情可能会变得笨拙,因为Artist_Group密钥的数据类型的长度需要一直变大。

于 2009-05-10T05:31:13.193 回答
1

我想我错过了“Artist_Group”关系的重点。

我心目中的数据模型是:

艺术家:个人。

歌曲:歌曲本身。

表演:歌曲的特定表演或编曲。通常这会有一首歌曲,但您可以提供一个 m:n 链接表来容纳混合曲目。理想情况下,这将是一个单一的真实表演,即,会有一个相关的日期。

录音:表演的特定固定版本(CD 或其他)。通常表演只有一个录音,但有一个单独的表可以处理 Grateful Dead / 多盗版场景,以及重新发行专辑、广播播放与现场与 CD 版本等。

Performance_Artists:从特定表演到表演者列表的链接表。对于每个人,您还可以有一个属性来描述他们在表演中的角色(歌手、鼓手等)。

一组表演者之间没有明确的关系,只是他们共同分享表演。因此,任何试图在录音上下文之外组合随机艺术家集的表都不是准确的关系模型,因为没有真正的关系。

如果您试图表示一组艺术家之间的明确关系(即,他们在同一个乐队中),那么乐队的名称具有唯一性(尽管不足以成为主键),并且可以存储一个乐队简单地作为一个艺术家,然后有一个 Artist_Member 链接表,它可以自引用回各个艺术家记录。或者你可以有一个单独的 Band 表和一个 Band_Members 表来为它分配艺术家,也许还有成员的日期。无论哪种方式,只要记住乐队成员会随着时间的推移而变化,乐队角色会从一首歌曲到另一首歌曲,因此将乐队与表演相关联不应代替将表演直接与相关艺术家联系起来。

于 2009-05-10T05:36:47.267 回答
0

我想您可以通过对艺术家 ID 进行排序和连接来构建主键?

组:3,2,6 -> 2-3-6 和 6,3,2 -> 2-3-6

于 2009-05-10T06:53:46.613 回答
0

我在 RDBMS 方面没有太多经验。但是,我读过 Codd 的论文和 CJ Date 的书籍。

所以,我不会使用 RDBMS 术语,而是尝试用更常见的有意义的术语来解释(至少对我来说!)

开始 -

  1. 歌手姓名应以“名 - 姓”为标准

  2. 每个“歌手”都应该在“艺人组”表中有一个条目,即使他们已经独奏

  3. “艺术家组”中的每个条目将由多个按字母顺序排列的“歌手”组成。特定组合应该只出现一次。

  4. 每首歌曲都将有一个来自“Artists Group”的独特唱片条目,无论它们是独奏、二重奏还是团伙。

我不知道这是否有意义,但这是我的两分钱!

于 2009-05-10T12:22:20.687 回答