我正在尝试创建一个数据库,用于存储每个家庭作业的学生成绩,我希望能够存储成绩以及该学生获得证书成绩的次数,例如学生得到A+ 30 times
,为每个学生,以及学生得到多少年级。一个等级的分值是多少,例如A is worth 4.3
。
所以我想知道构建我的MySQL数据库的最佳方法是什么,我需要添加什么以及我需要删除什么,以及如何存储像4.3
这样的数字。
我的数据库到目前为止
CREATE TABLE grades (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
grade INT UNSIGNED NOT NULL,
student_work_id INT UNSIGNED NOT NULL,
student_id INT UNSIGNED NOT NULL,
date_created DATETIME NOT NULL,
PRIMARY KEY (id)
);
CREATE TABLE work (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
student_id INT UNSIGNED NOT NULL,
title TEXT NOT NULL,
content LONGTEXT NOT NULL,
PRIMARY KEY (id)
);
CREATE TABLE IF NOT EXISTS student (
id int(8) NOT NULL auto_increment,
student varchar(20) NOT NULL,
PRIMARY KEY (`id`)
)
输出示例。
student | grade | count
1 A 10
1 C 2
1 F 4
2 B 20
2 B- 3
2 C+ 10
student | grade | points
1 A 4.3
2 B+ 3.3
3 B- 2.7
4 D+ 1.3
student | total grades
1 90
2 80
3 100
4 1
答案 0 :(得分:2)
我认为学生成绩 - 分配模式可以。您应该计算具有查询的学生的成绩数,而不是在数据库中维护该信息。 在概念层面(不严格的mysql),我会做这样的事情。
table student (
id int (primary key)
varchar name
... // other student attributes (e.g. phone number)
)
table grade (
id int (primary key)
name varchar // e.g. "A+", "B-", etc.
float points // grade value in points
)
table assignment (
id int (primary key)
name varchar // assignment name
student_id int (foreign key) // student that completed the particular assignment
grade_id int (foreign key) // grade achieved in particular assignment
... // other assignment attributes (e.g. due date)
)
答案 1 :(得分:1)
许多人会建议您有学生表,成绩表和与学生和成绩表相关的表格。然后,您可以根据将两者与过程相关联的表进行计数。许多人认为在同一张桌子上有一个成绩和一个学生的关系设计很差。
答案 2 :(得分:1)
除非你想使用一个在这种情况下真的不必要的视图,否则你不会存储学生获得某个等级的次数;相反,您会在需要时为每位学生提供一个查询信息。使用您当前架构的一个示例,告诉您具有身份st_id
的特定学生获得每个年级的次数,就像
SELECT COUNT(1) FROM grades WHERE student_id = st_id GROUP BY grade
这将查看学生st_id
获得每个成绩的所有行,并单独计算。
至于存储从字母等级到其值的点数的映射,您可以执行以下两种操作之一 - 要么具有从字母等级到点数量的表格映射,要么直接存储点数量。就个人而言,我认为前者有点清洁,因为如果规模发生变化(不是经常发生的话),它允许你改变点数。
除此之外,我觉得你做得很好。我唯一要说的是,如果在成绩和工作之间始终存在一对一的映射,我可能会将工作表的成绩作为工作表的一部分,而不是将它们分开。也就是说,只有等级表中没有不属于工作表的信息。
答案 3 :(得分:1)
看着你的桌子,看来你可以做一些规范化,或者我可能误解了目标。我认为学生和工作项目只是通过成绩连接,这将使您的成绩基本上成为交叉参考表。因此,您不会在工作表中引用student_id
列。脱下袖口,我会改变它,使表格看起来更像这样:
CREATE TABLE student (
student_id int(8) NOT NULL auto_increment,
student varchar(20) NOT NULL,
PRIMARY KEY (student_id)
);
CREATE TABLE work (
work_id INT UNSIGNED NOT NULL AUTO_INCREMENT,
title TEXT NOT NULL,
content LONGTEXT NOT NULL,
PRIMARY KEY (work_id)
);
CREATE TABLE grades (
grade_id INT UNSIGNED NOT NULL AUTO_INCREMENT,
grade decimal(4,2) UNSIGNED NOT NULL,
work_id INT UNSIGNED NOT NULL,
student_id INT UNSIGNED NOT NULL,
date_created DATETIME NOT NULL,
PRIMARY KEY (id)
);
请注意,我将成绩列更改为十进制(我是SQL Server人员,因此MySQL可能不同),但任何可以处理非整数数字的类型都可以。通过该设计,您可以根据需要提取查询以获得所需的输出类型。
约什
答案 4 :(得分:1)
假设 -
有多个学生
有多个作业/作品需要评分
我会去 -
用于定义每个工作片段/特定作业的表格。
定义每个学生的表格
第三个表格,记录每个学生每个作业的结果,即存储每个作业的成绩。
例如 -
CREATE TABLE work (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
student_id INT UNSIGNED NOT NULL,
assignment_id int unsigned not null,
grade DECIMAL(1,1)
gradedesc VARCHAR(1)
PRIMARY KEY (id)
);
CREATE TABLE IF NOT EXISTS student (
id int(8) NOT NULL auto_increment,
student varchar(20) NOT NULL
PRIMARY KEY (`id`)
)
Create table assignment (
id int(8) not null auto_increment,
title TEXT NOT NULL,
content LONGTEXT NOT NULL
primary key(id)
然后,创建一些视图以您想要的格式显示输出,例如 -
Create view graded_students as
(select s.student,
w.gradedesc as grade,
w.grade as points,
w.title
from work w,
student s
where w.student_id = s.id
and w.grade is not null )
Create view aggregate_grades as
(select s.student,
sum(w.grade) as "total grades",
from work w,
student s
where w.student_id = s.id
and w.grade is not null
group by s.student)
create view grades_by_assignment as
(select s.student,
a.title,
w.gradedesc as grade
from student s,
work w,
assignment a
where a.id = w.assignment_id
and s.id = w.student_id )
我更像是一个oracle和sql服务器的人,所以这可能不是100%的mysql兼容(我还没有测试过)但是这样的事情我会想到这个。
如果您想进一步规范化数据,您也可以将等级描述/值分解为另一个表,或者只根据存储的值在应用程序中显示等级描述(例如等级值4.5总是显示为“A” “等等)