我正在构建一个显示50年代和60年代的图表记录/专辑的网络应用程序。
目前我有类似的东西(删除了许多不相关的东西):
名为“group”的表曾被建模为“person”表,“person_group”连接表和“group”表。这个问题是我不能将外键'group_performance_role.group_id'引用到“人”和“组”表中。
我决定保留这种结构,但要求每个“人”自动成为1的“组”;然而,这会产生命名歧义,意味着该表包含多个内容 - 有时是一个艺术家(“John Lennon”),有时是一个Group(“The Beatles”)。
我需要找到一种方法来将艺术家(可能是一个人或一群人)与表演联系起来,同时避免不良行为,例如一个包含多种“类型”事物的表格。
我已经搜索了网络,但发现相关答案的方式很少。任何帮助/建议/建议非常感谢!!
编辑:“角色”表是人员/群组可以在演出中执行的角色的查找表。例如:“艺术家”,“作曲家”,“管弦乐指挥”等等
答案 0 :(得分:2)
你的最终目标是存储一个表演数据库吗?
所以演奏是由表演者的一些表演者执行的,由作曲家的一些作者安排,由制片人的某些作品制作。我认为你需要一个抽象的实体来代表所有这些可能性。我现在可以召唤的最好的名词是信用,因为你会“为你的名字扩展学分”。 (Morisette 1995)
所以,我想象的方式,你会有几个类别的信用,在第一级,我想这些是人,组这是一组人和组织,它们会像“Parlephone”或“Island Records”等。
这些信用类别可能有子类别,具体取决于您要存储的属性。但是,我认为每个 Performance 都会有一些 PerformanceCredit 关系,而每个 PerformanceCredit 关系都会有一个for strong指向 PerformanceCreditType 强>
这一切都忽略了与歌曲的任何关系,我认为这与演出在逻辑上是分开的,歌曲会有自己的 SongCredit < / strong>人际关系, SongCreditType “作家”是一个明显的想法。每个歌曲与多个效果 s
相关这一切都很好地延伸到录制(DVD,78,LP,MP3等),这将是性能的集合,但可以并且确实具有独立性信用的自己。
我认为这是有道理的,因为我假设您将从积分中获取此信息。
我认为你需要这种灵活性。考虑一下我是否想要报道与"Paul McCartney"有关的一切,他的直接学分,无论是独奏还是小组,作为作家,作曲家,音乐家和制作人都是巨大的。然后考虑他由其他音乐家编写和创作的歌曲的表演等。
答案 1 :(得分:2)
考虑使用inheritance为各种艺术家或艺术家建模:
(顺便说一句,你的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
正如您所看到的,我们不断使模型越来越精确,但也越来越复杂。而我们甚至还没有进入歌曲和专辑,也没有进化过小组成员(等等......)。我想你有责任决定“精确”和简单之间的平衡点。
答案 2 :(得分:1)
我认为你拥有它的方式可能有意义。我假设您正在分别对组和组成员/人员进行建模,因为您要对组和组成员执行不同的操作/操作(如果不是为什么要打扰建模组成员)。
如果是这种情况,那么我假设在John Lennon的情况下你希望能够对他执行Person操作和 Group操作,所以让他在DB中出现两次,作为一个团体和一个团体成员是有道理的,因为这两个实体代表约翰列侬在你的领域中扮演的不同角色。
答案 3 :(得分:0)
例如
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