9

我正在为一所学校的学生建立一个数据库。这是我目前所拥有的: 在此处输入图像描述

如果您不喜欢阅读,请跳至“简而言之”部分

问题是我对这个设计不满意。我希望 和 的组合是唯一的gradesubgradeid_class作为学生表的主键。我可以student_id从 3 中删除并制作一个复合键,但我也不想要那个。也许我应该制作另一个表,让我们说combination_idwhere和是外键grade,并且有一个额外的列用作表的 ID。所有的列都将是主键。但问题是这 3 列仍然可以重复,因为有额外的列 ( )。例如,我可以有相同的,但不同的,这将使行有效,因为表的 4 列的复合键(subgradeid_classcomb_idcomb_idgradesubgradeclass_idcomb_idcombination_id)。

简而言之,我想students_id保留该表的唯一主键,但要成为另一个表的外键,该表在某种程度上是grades,subgrade和的唯一组合class_id

如果我不够清楚,请在下面的评论中提问,并提前感谢您。

PS我很抱歉标题难以描述,但我不擅长命名

编辑 1: 更清楚一点: grade可以是 1 到 12 subgrade可以是 a 到 j id_class可以是 1 到 30,这是你在课堂上的号码

所以一个学生可以来自 7b 班级,他的班级人数 - 5

4

3 回答 3

27

不要混淆唯一键主键的概念。您可以很好地添加一个跨越三列的唯一键gradessubgrade并且class_id. 这样,对于这三列,没有两行可以具有相同的值。当您写到您不想将这三个作为复合主键时,我不确定复合唯一补充键是否会更好。如果不是,您必须澄清何时可以接受复合键。

要创建唯一键,您可以使用以下 SQL语句

ALTER TABLE students ADD UNIQUE gsc (grades, subgrade, class_id);

这个词gsc只是我从关键列的首字母组成的一个名字;EXPLAIN使用您想要的任何名称,因为除非您想在某些输出或类似内容中识别密钥,否则这无关紧要。

于 2012-08-02T08:43:51.817 回答
3

我不完全清楚你为什么想要你所描述的,但我会以以下方式查看模型......

你有学生
——他们是不同的实体,而不是其他实体的组合
——他们有自己的属性;姓名、出生日期等

你有班级
- 这些是学生群体
- 每个学年同一个“班级”有不同的学生
- 他们也有自己的属性;等级、次等级等

您的模型中有一个我通常不会使用的额外属性
- 如果一个班级有 20 名学生,则每个学生都用从 1 到 20 的辅助 id 标识


这会给以下维度表

Student                  Class                     Grade              SubGrade
-----------------------  ------------------------  -----------------  -----------------
id          INT PK       id           INT PK       id    INT PK       id    INT PK
first_name  VARCHAR(45)  name         VARCHAR(45)  name  VARCHAR(45)  name  VARCHAR(45)
last_name   VARCHAR(45)  grade_id     INT FK       desc  VARCHAR(45)  desc  VARCHAR(45)
etc, etc                 subgrade_id  INT FK       etc, etc           etc, etc

Class表将有一个唯一的约束,(grade_id, subgrade_id)因此只有一个类可以是7b.

然后你需要使用事实表将学生与他们的班级联系起来......

Class_Membership
-----------------------
id               INT PK
student_id       INT FK
class_id         INT FK
academic_year    INT

如果一个学生在任何一个学年都应该只上一个班级,那么您将对(student_id, academic_year).

Class或者,您可以在表中列出学年。这意味着您每年都会重复上同一门课,但在某些年份7g可能不存在该课程(例如,那一年的学生较少)

同样,你可以让学生从7b7c中转学。在这种情况下,Class_Membership表可能有一个start_date字段,也可能有一个end_date字段。


然而,这些都没有直接创建id_class字段(1-20 代表一个有 20 名学生的班级)。就我个人而言,我不会有这样的字段,表中的id字段Class_Membership可以提供大多数相同的功能,并且可能还有其他功能。但是,如果必要,您可以简单地将其添加到Class_Membership表中......

Class_Membership
-----------------------
id               INT PK
student_id       INT FK
class_id         INT FK
academic_year    INT
class_member_id  INT

那么你也可以对(academic_year, class_id, class_member_id).


这里有很大的灵活性,具体取决于您确切的真实世界模型和您的特定需求。但希望这个例子对你来说是一个好的开始;列出实体的维度表,以及将这些实体关联在一起和/或进一步描述实体的事实表(或多个表)。

于 2012-08-02T09:46:10.587 回答
-1
alter table <TableName> add constraint <ConstraintName> unique(<col1>, <col2>)

Modified the answer due to syntax mistakes. Mentioned above is correct.
于 2016-03-31T05:11:54.153 回答