問題は、1つのサブタイプの1つのオブジェクトだけが、親クラスの任意の行を参照するようにすることです。 @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),
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)
);
これは、@mikegによって言及された互いに素なサブタイプの例です。
@Countably Infiniteと@Peterによるコメントを再確認してください:
2つのテーブルへのINSERTには、2つの挿入ステートメントが必要です。しかし、これは、子テーブルがある場合はいつでもSQLにも当てはまります。普通のことです。
UPDATEには2つのステートメントが必要な場合がありますが、一部のブランドのRDBMSは、JOIN構文を使用したマルチテーブルUPDATEをサポートしているため、1つのステートメントで実行できます。
データをクエリするときは、media
をクエリするだけで実行できます。 共通列に関する情報のみが必要な場合は、表:
SELECT name, url FROM media WHERE media_id = ?
映画をクエリしていることがわかっている場合は、1回の結合で映画固有の情報を取得できます:
SELECT m.name, v.release_date
FROM media AS m
INNER JOIN movies AS v USING (media_id)
WHERE m.media_id = ?
特定のメディアエントリの情報が必要で、そのタイプがわからない場合は、そのようなサブタイプテーブルが1つだけ一致することを知って、すべてのサブタイプテーブルに参加する必要があります。
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になります。