Правильно, проблема в том, что вы хотите, чтобы только один объект одного подтипа ссылался на любую данную строку родительского класса. Начиная с примера , заданного @Jay S, попробуйте следующее:
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, 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)
);
Это пример непересекающихся подтипов , упомянутых @mike g.
Re комментарии @Counbly Infinite и @Peter:
Для вставки в две таблицы потребуется два оператора вставки. Но это также верно в SQL каждый раз, когда у вас есть дочерние таблицы. Это обычная вещь.
UPDATE может потребовать два оператора, но некоторые бренды СУБД поддерживают UPDATE для нескольких таблиц с синтаксисом JOIN, поэтому вы можете сделать это одним оператором.
При запросе данных вы можете сделать это, просто запросив таблицу media
, если вам нужна только информация об общих столбцах:
SELECT name, url FROM media WHERE media_id = ?
Если вы знаете, что запрашиваете фильм, вы можете получить информацию о фильме с помощью одного соединения:
SELECT m.name, v.release_date
FROM media AS m
INNER JOIN movies AS v USING (media_id)
WHERE m.media_id = ?
Если вам нужна информация для данной медиа-записи, и вы не знаете, какой это тип, вам придется присоединиться ко всем вашим таблицам подтипов, зная, что будет соответствовать только одна такая таблица подтипов:
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 = ?
Если данный носитель является фильмом, тогда все столбцы в t.*
будут иметь значение NULL.