You sad it - you need a performer
linked to act
, not band
or artist
. I mean you need an abstraction about the object linked to the act
object. The performer
will be then linked first to the band
object and second to the artist
. You'll need to determine grammatically if a performer is a band or an independent artist depending on the present link to one of both objects.
And of course you need a many-to-many relation between band and artist.
Something like this:
band(id PK, name)
artist(id PK, first_name, last_name)
band_artists(band_id, artist_id)
performer(id PK, band_id, artist_id)
act(id PK, performer_id, music_id)
music(id, song_name, release_year)
I would not recommend you to use only one object for both band and artist because they have different meaning and own life. In the future you may want to add some physical characteristics to the artist for instance that are not relevant to a bad and so on.
It will be easy to know when a performer is a band or an artist. In the first case you'll have a non-NULL value for the band_id field. In the second you'll have a NULL value in the band_id and non-NULL value in the artist_id field.
If you need to retrieve an information about the performer related to a song for example you can do it in the following way:
SELECT
music.song_name,
performer.id as performer_id,
group.name as group_name,
artist.first_name,
artist.second_name
FROM music
LEFT JOIN act on music.id = act.music_id
LEFT JOIN performer on act.performer_id = performer.id
LEFT JOIN band on performer.band_id = band.id
LEFT JOIN artist on performer.artist_id = artist.id
Now if your program logic you need to calculate
the performer name:
if performer.band_name is not None:
performer.name = performer.band_name
else:
performer.name = performer.first_name + ' ' + performer.last_name
I believe the example code is self explanatory even itś not in your programming language and given there is some preprocessing of the query's result to obtain the performer
object used in the example.