2

我正在构建一个 Web 应用程序,显示 50 年代和 60 年代的图表记录/专辑。

目前我有这样的东西(删除了很​​多不相关的东西):

group_performance_role

名为“group”的表曾被建模为“person”表、“person_group”连接表和“group”表。问题是我不能让外键“group_performance_role.group_id”同时引用“person”和“group”表。

我决定保留这种结构,但要求每个“人”自动成为 1 的“组”;但是,这会造成命名上的歧义,并且意味着该表包含多个东西 - 有时是单个艺术家(“John Lennon”),有时是一个组(“The Beatles”)。

我需要找到一种方法将艺术家(可能是一个人或一群人)与表演联系起来,同时避免不良做法,比如一张桌子可以容纳多个“类型”的东西。

网上搜索过,但几乎没有找到相关答案。非常感谢任何帮助/建议/建议!

编辑: “角色”表是人员/团体可以在表演中执行的角色的查找表。示例:“艺术家”、“作曲家”、“管弦乐队指挥”等

4

4 回答 4

3

考虑使用继承来建模各种类型或艺术家:

(顺便说一句,你的Group_Member桌子允许分组。我猜这不是你想要的。)

在此处输入图像描述

但是,这忽略了角色可能因艺术家类型而产生的任何差异。例如,让整个团队成为“指挥者”是没有意义的。如果强制执行这些类型的约束很重要,您可以采用“蛮力”方法并将特定于个人的角色与特定于组的角色分开:

在此处输入图像描述

(顺便说一句,如果您想防止特定于组的角色名称和特定于个人的角色名称重叠,则必须将两个角色表放在继承层次结构中。此处未显示。)

当然,这仍然不尊重某些角色的基数。例如,只有一个人(每场演出)可以成为“指挥”。为了解决这个问题,您必须进一步扩展模型:

在此处输入图像描述

并且可能必须为这些团体做类似的事情。

27要通过这三种角色中的任何一种让所有参与给定表演的人(比如),您需要一个类似于以下的查询:

SELECT *
FROM Person
WHERE person_id IN (

    SELECT person_id
    FROM Group_Person JOIN Group_Performance_Role
        ON Group_Person.group_id = Group_Performance_Role.group_id
    WHERE performance_id = 27

    UNION

    SELECT person_id
    FROM Person_Performance_MultiRole
    WHERE performance_id = 27

    UNION

    SELECT person_id
    FROM Person_Performance_SingleRole
    WHERE performance_id = 27

)

请注意,这最多只列出一次人员,即使他们参与了多个角色的表演(例如,同一个人可以是“指挥”,并且是在同一表演中扮演角色的组的成员)。

要获取他们的角色名称,您可以

SELECT Person.*, group_role_name
FROM Person
    JOIN Group_Person
        ON Person.person_id = Group_Person.person_id
    JOIN Group_Performance_Role
        ON Group_Person.group_id = Group_Performance_Role.group_id
WHERE performance_id = 27

UNION ALL

SELECT Person.*, person_multirole_name
FROM Person
    JOIN Person_Performance_MultiRole
        ON Person.person_id = Person_Performance_MultiRole.person_id
WHERE performance_id = 27

UNION ALL

SELECT Person.*, person_singlerole_name
FROM Person
    JOIN Person_Performance_SingleRole
        ON Person.person_id = Person_Performance_SingleRole.person_id
WHERE performance_id = 27

如您所见,我们不断使模型越来越精确,但也越来越复杂。而且我们甚至还没有进入歌曲和专辑,以及不断发展的团体成员(等等......)。我想你有责任决定“精确”和简单之间的正确平衡在哪里。

于 2012-09-20T10:09:10.053 回答
2

您的最终目标是存储表演数据库,对吗?

因此,一场表演是由某类表演者进行的,由某类作曲家安排,由某类制作人制作等。我认为你需要一个抽象的实体来代表所有这些可能性。我现在能召唤的最好的名词是Credit,因为你会“为你的名字扩展学分”。(莫里塞特 1995 年

所以,按照我的想象,你会有几个类别Credit,在第一层我想象这些是PersonGroup是一组PersonOrganization,类似于“Parlephone”或“Island Records”等.

这些信用类别可能有子类别,具体取决于您希望存储的属性。但是,我想每个Performance都会有许多PerformanceCredit关系,并且每个PerformanceCredit关系都有一个PerformanceCreditType的外键。


所有这一切都忽略了与Song的任何关系,我认为这在逻辑上与Performance是分开的,Song会有自己的SongCredit关系,SongCreditType “Writer”是显而易见的关系。每首乐曲都与许多Performance相关

这一切都很好地扩展到了Recording(DVD、78、LP、MP3 等),这将是Performance的集合,但可以并且确实拥有自己的独立Credit


我认为这是有道理的,因为我假设您将从学分中获得这些信息。

我认为您需要这种级别的灵活性。考虑一下,如果我想报道与“保罗·麦卡特尼”有关的所有事情,他作为作家、作曲家、音乐家和制作人的直接作品,无论是独奏还是团体,都是巨大的。然后考虑他写的其他音乐家等创作的歌曲的表演。

于 2012-09-20T09:15:53.460 回答
1

我认为你拥有它的方式可能是有道理的。我假设您要分别对组和组成员/人员进行建模,因为您要对组和组成员执行不同的操作/操作(如果不是,为什么要为组成员建模)。

如果是这种情况,那么我假设在 John Lennon 的情况下,您希望能够对他执行 Person 操作Group 操作,因此让他作为 Group 和 Group Member 在数据库中出现两次是有道理的,因为这两个实体代表约翰列侬在您的领域中扮演的不同角色。

于 2012-09-20T08:45:34.283 回答
0
  • 一张唱片有很多歌曲。
  • 每首歌曲都有一个艺术家 - 有一个名字。
  • 艺术家有一个或多个版本
  • 一个 ArtistVersion 有一个或多个成员是表演者

例如

Records : 
   1 Give Peace a Chance
   2 Penny Lane

Artists
   3 The Beatles
   4 Plastic Ono Band

Songs 
   5 4 Give Peace a Chance
   6 3 Penny Lane
   7 3 Strawberry Fields Forever

RecordSongs
   1 - 5
   2 - 6
   2 - 7

ArtistVersions
   8 - The Beatles v1 
   9 - Plastic Ono Band v1

Performers
   10 - Ringo Starr
   11 - John Lennon
   12 - Yoko Ono

ArtistVersionMembers
   8 - 10 
   8 - 11
   9 - 11
   9 - 12
于 2012-09-20T09:14:40.637 回答