Đúng vậy, vấn đề là bạn chỉ muốn một đối tượng của một kiểu con tham chiếu đến bất kỳ hàng nhất định nào của lớp cha. Bắt đầu từ ví dụ do @Jay S đưa ra, hãy thử điều này:
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)
);
Đây là ví dụ về các kiểu phụ rời rạc được @mike g đề cập.
Nhận xét lại bởi @Countably Infinite và @Peter:
CHÈN vào hai bảng sẽ yêu cầu hai câu lệnh chèn. Nhưng điều đó cũng đúng trong SQL bất cứ khi nào bạn có bảng con. Đó là một việc bình thường để làm.
CẬP NHẬT có thể yêu cầu hai câu lệnh, nhưng một số thương hiệu RDBMS hỗ trợ CẬP NHẬT nhiều bảng với cú pháp THAM GIA, vì vậy bạn có thể thực hiện điều đó trong một câu lệnh.
Khi truy vấn dữ liệu, bạn có thể thực hiện điều đó đơn giản bằng cách truy vấn media
bảng nếu bạn chỉ cần thông tin về các cột chung:
SELECT name, url FROM media WHERE media_id = ?
Nếu bạn biết mình đang truy vấn một bộ phim, bạn có thể nhận thông tin về bộ phim cụ thể với một phép nối duy nhất:
SELECT m.name, v.release_date
FROM media AS m
INNER JOIN movies AS v USING (media_id)
WHERE m.media_id = ?
Nếu bạn muốn có thông tin cho một mục nhập phương tiện nhất định và bạn không biết loại đó là gì, bạn phải kết hợp với tất cả các bảng loại phụ của mình, biết rằng chỉ một bảng loại phụ như vậy sẽ phù hợp:
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 = ?
Nếu phương tiện đã cho là phim thì tất cả các cột trong t.*
sẽ là NULL.