À droite, le problème est que vous ne voulez qu'un seul objet d'un sous-type pour référencer une ligne donnée de la classe parent. En partant de l'exemple donné par @Jay S, essayez ceci :
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)
);
Ceci est un exemple des sous-types disjoints mentionnés par @mike g.
Concernant les commentaires de @Countably Infinite et @Peter :
INSERT à deux tables nécessiterait deux instructions d'insertion. Mais c'est également vrai en SQL chaque fois que vous avez des tables enfants. C'est une chose ordinaire à faire.
UPDATE peut nécessiter deux instructions, mais certaines marques de RDBMS prennent en charge UPDATE multi-tables avec la syntaxe JOIN, vous pouvez donc le faire en une seule instruction.
Lorsque vous interrogez des données, vous pouvez le faire simplement en interrogeant le media
table si vous n'avez besoin que d'informations sur les colonnes communes :
SELECT name, url FROM media WHERE media_id = ?
Si vous savez que vous interrogez un film, vous pouvez obtenir des informations spécifiques au film avec une seule jointure :
SELECT m.name, v.release_date
FROM media AS m
INNER JOIN movies AS v USING (media_id)
WHERE m.media_id = ?
Si vous voulez des informations pour une entrée de média donnée, et que vous ne savez pas de quel type il s'agit, vous devrez vous joindre à toutes vos tables de sous-types, sachant qu'une seule de ces tables de sous-types correspondra :
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 = ?
Si le média donné est un film, alors toutes les colonnes de t.*
sera NULL.