如何使复合键具有独特性?

时间:2012-08-02 08:19:32

标签: mysql sql database-design uml composite-key

我正在一所学校建立一个学生数据库。这是我到目前为止所拥有的: enter image description here

如果您不喜欢阅读跳转到“简短”部分

问题在于我对这种设计不满意。我希望gradesubgradeid_class的组合是唯一的,并且可以作为学生表的主键。 我可以删除student_id并从3中创建一个复合键,但我也不想要。也许我应该制作另一个表格,让我们说combination_id gradesubgradeid_class是外键,还有一个额外的列comb_id作为ID桌子。所有列都是主键。但问题是由于额外的列(comb_id),这3列仍然可以重复。例如,我可以使用相同的gradesubgradeclass_id,但不同的comb_id会使该行有效,因为该表的4列的复合键( combination_id)。

简而言之,我希望students_id仍然是表的唯一主键,但要成为另一个表的外键,这是gradessubgrade和{{的某种独特组合。 1}}。

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

PS 我很抱歉这个愚蠢的头衔,但我擅长命名

编辑1: 更清楚: class_id可以是1到12 grade可以是j subgrade可以是1到30,这是您在班级中的号码

所以一个学生可以从7b班级和他的班级编号 - 5

3 个答案:

答案 0 :(得分:19)

不要混淆唯一键主键的概念。您可以在gradessubgradeclass_id这三列中添加unique key。这样,这三列没有两行could have相同的值。当你写这篇文章时,你不希望将这三个作为复合主键,我不确定复合唯一补充键是否会更好。如果没有,您必须澄清何时可以接受复合键。

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

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

单词gsc只有一个名字,我是从关键列的首字母组成的;使用你想要的任何名称,因为它几乎不重要,除非你想在某些EXPLAIN输出中识别密钥或类似名称。

答案 1 :(得分:3)

我不清楚为什么你想要你所描述的内容,但我会以下列方式看待这个模型......

你有学生 - 它们是不同的实体,而不是其他实体的组合 - 他们有自己的财产;姓名,出生日期等

你有班级 - 这些是学生群体 - 每个学术年份相同的“班级”都有不同的学生 - 他们也有自己的财产;等级,次级等

您的模型中有一个我通常不会使用的额外属性 - 如果一个班级有20名学生,则每个学生都会被识别为次要ID为1到20


这将为 me 提供以下维度表

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可能不存在(例如,那年的学生数量较少)。< / p>

同样,您可以让学生在年中从7b转移到7c。在这种情况下,Class_Membership表可能包含start_date字段,可能还有end_date字段。


但是,这些都不会直接创建id_class字段(对于有20名学生的课程为1-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)上设置唯一约束。


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

答案 2 :(得分:0)

alter table <TableName> add constraint <ConstraintName> unique(<col1>, <col2>)

Modified the answer due to syntax mistakes. Mentioned above is correct.