对,问题是您只希望一种子类型的一个对象引用父类的任何给定行。从@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)
);
这是@mike g提到的不相交子类型的一个示例。
回复@Countably Infinite 和@Peter 的评论:
插入两个表需要两个插入语句。但是,只要您有子表,在 SQL 中也是如此。这是一件很平常的事情。
UPDATE 可能需要两条语句,但某些品牌的 RDBMS 支持使用 JOIN 语法的多表 UPDATE,因此您可以在一条语句中完成。
查询数据时,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。