継承を使用して、さまざまな種類またはアーティストをモデル化することを検討してください。
(ところで、あなたのGroup_Member
テーブルはグループ内のグループを許可しています。これはあなたが望んでいたものではないと思います。)
ただし、これは、アーティストのタイプに応じて役割が異なる可能性があることを無視しています。たとえば、グループ全体が「指揮者」になることはほとんど意味がありません。これらの種類の制約を強制することが重要な場合は、「強引な」アプローチを取り、個人固有の役割とグループ固有の役割を単純に分離できます。
(ところで、グループ固有のロールと個人固有のロールの名前が重複しないようにする場合は、両方のロール テーブルを継承階層に配置する必要があります。ここには示されていません。)
もちろん、これはまだ特定の役割のカーディナリティを尊重していません。たとえば、「指揮者」になれるのは(1公演につき)1人だけです。それを解決するには、モデルをさらに拡張する必要があります。
そして、おそらく同様のことをグループに対して行う必要があります。
これら 3 種類のロールのいずれかを通じて、特定のパフォーマンス (たとえば ) に関与するすべての人を取得するには、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
)
これは、複数の役割でパフォーマンスに関与している場合でも、人を最大 1 回しかリストしないことに注意してください (たとえば、同じ人が「指揮者」であり、同じパフォーマンスで役割を持つグループのメンバーになることができます)。
ロール名も取得するには、次のことができます。
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
ご覧のとおり、私たちはモデルをますます正確にすると同時に、ますます複雑にしています。そして、曲やアルバム、進化するグループ メンバー (など...) についてはまだ触れていません。「精度」と単純さの間の適切なバランスがどこにあるかを判断する責任はあなたにあると思います。