This type of "one-of" modeling is tricky. Some databases have built-in support for such functionality, such as inheritance.
One method is to have an attachments
table and to combine all into one table. This would have columns such as:
attachments_id
type check type in ('video', 'audio', . . .)
- columns needed for any of them.
More commonly, each of these would be a separate entity, because the columns describing them would be quite different -- and often have their own relationships. In this case, a simple method for a handful of types is a separate column for each one, along with a constraint that at most one is not NULL
:
check ( (case when video_id is not null then 1 else 0 end) +
(case when audio_id is not null then 1 else 0 end) +
. . . <= 1
)
This allows properly declared foreign key relationships.
Another method is a variation on this. Assuming that all the id columns have the same type, then use the columns:
attachment_type varchar(255) check (attachment_type in ('video', 'audio', . . .),
attachment_id int
The type would determine the type of id
, but the database would not validate this.
And another method is a more complex inheritance pattern, which involves setting up individual tables for each entity, along with a type in each one. And then setting up an attachments
table. This looks like:
attachments_id int generated always as identity primary key,
attachment_type varchar(255) check (attachment_type in ('video', 'audio', . . .),
unique (type, attachments_id)
And then:
video_id int primary key,
type varchar(255) generated always as
foreign key video_id references (type, attachments_id)
and so on for the other tables. This sets up a foreign key relationship to attachments
and makes sure that the types match.