Giusto, il problema è che vuoi che solo un oggetto di un sottotipo faccia riferimento a una determinata riga della classe genitore. Partendo dall'esempio fornito da @Jay S, prova questo:
create table media_types (
media_type int primary key,
media_name varchar(20)
);
insert into media_types (media_type, media_name) values
(2, 'TV series'),
(3, 'movie');
create table media (
media_id int not null,
media_type not null,
name varchar(100),
description text,
url varchar(255),
primary key (media_id),
unique key (media_id, media_type),
foreign key (media_type)
references media_types (media_type)
);
create table tv_series (
media_id int primary key,
media_type int check (media_type = 2),
season int,
episode int,
airing date,
foreign key (media_id, media_type)
references media (media_id, media_type)
);
create table movies (
media_id int primary key,
media_type int check (media_type = 3),
release_date date,
budget numeric(9,2),
foreign key (media_id, media_type)
references media (media_id, media_type)
);
Questo è un esempio dei sottotipi disgiunti menzionati da @mike g.
Re commenti di @Countably Infinite e @Peter:
INSERT su due tabelle richiederebbe due istruzioni di inserimento. Ma questo è vero anche in SQL ogni volta che hai tabelle figlio. È una cosa normale da fare.
UPDATE potrebbe richiedere due istruzioni, ma alcuni marchi di RDBMS supportano UPDATE multi-table con sintassi JOIN, quindi puoi farlo in un'unica istruzione.
Quando esegui una query sui dati, puoi farlo semplicemente interrogando il media
tabella se hai bisogno solo di informazioni sulle colonne comuni:
SELECT name, url FROM media WHERE media_id = ?
Se sai che stai interrogando un film, puoi ottenere informazioni specifiche sul film con un unico join:
SELECT m.name, v.release_date
FROM media AS m
INNER JOIN movies AS v USING (media_id)
WHERE m.media_id = ?
Se desideri informazioni per una determinata voce multimediale e non sai di che tipo si tratta, dovresti unirti a tutte le tabelle di sottotipi, sapendo che solo una di queste tabelle di sottotipi corrisponderà:
SELECT m.name, t.episode, v.release_date
FROM media AS m
LEFT OUTER JOIN tv_series AS t USING (media_id)
LEFT OUTER JOIN movies AS v USING (media_id)
WHERE m.media_id = ?
Se il file multimediale specificato è un film, tutte le colonne in t.*
sarà NULL.