sql 中的自然复合键与单个代理键

Natural Composite Key vs Single Surrogate Key in sql

提问人:Geek 提问时间:11/14/2023 最后编辑:marc_sGeek 更新时间:11/14/2023 访问量:33

问:

create table Section
(
    section_surr_id serial not null,
    curr_id int,
    section_id int not null,
    foreign key (curr_id) references Curriculum(curr_id)
);

create table Lesson
(
    lesson_surr_id serial not null,
    curr_id int,
    section_id int, 
    lesson_id int not null,
    uri varchar not null,
    title varchar not null,
    description varchar,
    foreign key (curr_id) references Curriculum(curr_id),
    foreign key (section_id) references Section(section)
);

以下是我想做什么的大致概述:课程有很多部分;每个部分都有很多课程

在表格中,我想包括,因为每节课都属于一个特定的部分;但是我已经为唯一标识每个部分的部分创建了一个代理键。Lessonsection_id

原因是每个课程都有很多部分,所以如果我做了主键,那么它就可以重复,就像课程 1 的第 1 部分和课程 2 的第 1 部分一样;因此,我有两个选择:section_id

  • 创建一个由 和 组成的复合自然键curr_idsection_id
  • 或创建代理项单列主键

现在我在课程中引用什么键;如果我引用代理键,那么这将是不自然的,因为我必须寻找我想要引用的部分的代理键,例如所需课程的 1、2、3 等。

SQL PostgreSQL 数据库设计

评论


答:

0赞 Bill Karwin 11/14/2023 #1

“正确”的答案不止一个,所以这接近于一个基于意见的问题,Stack Overflow 不鼓励这样做。

我会创建一个复合主键。

create table Section
(
    curr_id int not null,
    section_id int not null,
    primary key (curr_id, section_id),
    foreign key (curr_id) references Curriculum(curr_id)
);

然后使用复合外键引用它。固执己见的部分是,可以将序列号保留在表中,也可以不保留。以下任一情况均正确:Lesson

create table Lesson
(
    lesson_surr_id serial not null,
    curr_id int not null,
    section_id int not null, 
    lesson_id int not null,
    uri varchar not null,
    title varchar not null,
    description varchar,
    foreign key (curr_id, section_id) references Section(curr_id, section_id)
);

create table Lesson
(
    curr_id int not null,
    section_id int not null, 
    lesson_id serial not null,
    uri varchar not null,
    title varchar not null,
    description varchar,
    primary key (curr_id, section_id, lesson_id),
    foreign key (curr_id, section_id) references Section(curr_id, section_id)
);

这归结为个人喜好。