以下是您的 DDL(数据定义语言)的外观,带有一些示例插入:
create table playlist
(
playlist_id numeric(10) not null,
playlist_name varchar(25),
constraint p_id_pk primary key (playlist_id)
);
create table songs
(
song_id numeric(10) not null,
song_name varchar(25),
constraint s_id_pk primary key (song_id)
);
create table playlist_songs
(
playlist_id,
song_id,
song_order int,
constraint p_fk foreign key (playlist_id) references playlist(playlist_id),
constraint s_fk foreign key (song_id) references songs(song_id)
);
insert into playlist values (1, 'A cool playlist');
insert into playlist values (2, 'An okay playlist');
insert into songs values (1, 'ABC');
insert into songs values (2, 'DEF');
insert into songs values (3, 'GHI');
insert into songs values (4, 'JKL');
insert into playlist_songs values (1, 1, 1);
insert into playlist_songs values (1, 3, 2);
insert into playlist_songs values (2, 2, 1);
insert into playlist_songs values (2, 3, 2);
小提琴: http://sqlfiddle.com/#!4/0420f/5/0
还有一个您可能会运行的 SELECT 查询示例:
select ps.playlist_id,
p.playlist_name,
s.song_id,
s.song_name,
ps.song_order
from playlist_songs ps
join songs s
on ps.song_id = s.song_id
join playlist p
on ps.playlist_id = p.playlist_id
order by ps.playlist_id, ps.song_order
输出:
| PLAYLIST_ID | PLAYLIST_NAME | SONG_ID | SONG_NAME | SONG_ORDER |
|-------------|------------------|---------|-----------|------------|
| 1 | A cool playlist | 1 | ABC | 1 |
| 1 | A cool playlist | 3 | GHI | 2 |
| 2 | An okay playlist | 2 | DEF | 1 |
| 2 | An okay playlist | 3 | GHI | 2 |
中间表的目的是数据规范化。它减少了您存储的数据量并允许更好地控制数据。
在系统中,您有一个歌曲库。用户可以创建播放列表并将歌曲分配给这些播放列表。您有歌曲、播放列表以及将歌曲分配到播放列表。
这些信息可以以非规范化方式组合(例如在上面的查询结果中),但非规范化数据主要用于报告。存储数据时,您不希望将相同的数据存储在多个位置。您不应该看到存储在两个地方的播放列表的名称。或者一首歌的名字存储在两个地方。您将存储冗余数据。此外,当某些事情发生变化时,比如歌曲的大小(当前未包含在您的架构中,但可能包含),显然能够只更新歌曲表的 1 行,而不是可能的数千行任何类型的非规范化表。
非规范化表确实在报告环境中占有一席之地,因为它们在选择用于报告和分析的数据时涉及较少的表连接。这些表更宽,包含用户经常在查询中查找的信息。同样,分区也可以在运行某些查询时产生显着的性能提升。