Mysql 如何使复合密钥唯一?

Mysql 如何使复合密钥唯一?,mysql,sql,database-design,uml,composite-key,Mysql,Sql,Database Design,Uml,Composite Key,我正在为一所学校的学生制作一个数据库。以下是我目前掌握的信息: 如果你不喜欢阅读,跳到“简短”部分 问题是我对这个设计不满意。我希望grade、subgrade和id\u class的组合是唯一的,并作为students表的主键。 我可以删除学生id并从3中生成一个复合键,但我也不希望这样。也许我应该制作另一个表,比如说combination\u id,其中grade,subgrade和id\u class是外键,另外还有一列comb\u id作为表的id。所有列都将是主键。但问题是,由于额外

我正在为一所学校的学生制作一个数据库。以下是我目前掌握的信息:

如果你不喜欢阅读,跳到“简短”部分

问题是我对这个设计不满意。我希望
grade
subgrade
id\u class
的组合是唯一的,并作为students表的主键。 我可以删除
学生id
并从3中生成一个复合键,但我也不希望这样。也许我应该制作另一个表,比如说
combination\u id
,其中
grade
subgrade
id\u class
是外键,另外还有一列
comb\u id
作为表的id。所有列都将是主键。但问题是,由于额外的列(
comb\u id
),这3列仍然可以重复。例如,我可以使用相同的
等级
路基
等级id
,但不同的
组合id
,这将使行有效,因为表中4列的组合键(
组合id

简言之,我希望
students\u id
仍然是表中唯一的主键,但作为另一个表的外键,该表是
成绩
基础
班级id
的独特组合

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

PS我很抱歉这个不成文的标题,但我不擅长命名

编辑1: 更清楚地说:
等级
可以是1到12
路基
可以是a到j
id\u class
可以是1到30,这是你在班上的号码

因此,一个学生可以来自7b班,他的数字在-5班。不要混淆单键和主键的概念。您可以很好地在
坡度
路基
class_id
三列中添加一个。这样,这三列中没有两行的值相同。当您写到您不想将这三个作为复合主键时,我不确定复合唯一补充键是否会更好。如果没有,您必须澄清何时可以接受复合键

要创建唯一密钥,可以使用以下SQL:


单词
gsc
只有一个名字是我根据关键列的首字母缩写拼成的;使用您想要的任何名称,因为这几乎不重要,除非您想在一些
解释
输出或类似输出中识别键。

我不完全清楚您为什么要使用您所描述的名称,但我将以以下方式查看模型

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

你有课
-这些是学生小组
-每一学年同一个“班级”都有不同的学生
-他们也有自己的财产;斜坡、路基等

您的模型中有一个我通常不会使用的额外属性
-如果一个班级有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
表将对
(grade\u id,subgrade\u id)
具有唯一的约束,因此只有一个类可以是
7b

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

Class_Membership
-----------------------
id               INT PK
student_id       INT FK
class_id         INT FK
academic_year    INT
如果一个学生在任何学年只能在一个班级上课,您将对
(学生id,学年)
设置一个唯一的约束

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

同样,你可以让学生在年中从
7b
转到
7c
。在这种情况下,
Class\u Membership
表可以有一个
start\u date
字段,也可能有一个
end\u date
字段


但是,所有这些都不会直接创建
id\u class
字段(对于一个有20名学生的班级为1-20名)。就我个人而言,我不会有这样一个字段,来自
Class_Membership
表的
id
字段可以提供大部分相同的功能,可能还有其他功能。但是,如果有必要,您可以简单地将其添加到
Class\u成员资格
表中

Class_Membership
-----------------------
id               INT PK
student_id       INT FK
class_id         INT FK
academic_year    INT
class_member_id  INT
然后您还可以对
(学年、班级id、班级成员id)
有唯一的约束


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

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

Modified the answer due to syntax mistakes. Mentioned above is correct.
由于语法错误,修改了答案。上面提到的是正确的。
我不明白,一个班里的所有学生都应该有不同的成绩吗?当学生换班时,你会怎么做?或者,这不会发生吗?学生id列有什么问题吗?只有一个班的学生,像小学/初中/幼儿学校吗?@Jodrell我编辑了我的问题,以便更清楚地了解这些专栏。我希望
student\u id
是另一个表中的FK,该表包含作为复合键的3列。如果你仍然有问题问我,我会试试看,我可能会把人们与
等级
路基
id\u班级
的名称混淆了,但在我的国家,教育系统是不同的。好吧,我试过了,但当我把所有3列都设置为唯一时,我犯了一个错误
alter table <TableName> add constraint <ConstraintName> unique(<col1>, <col2>)

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