2010-01-08 84 views
2

我正在尝试创建一个数据库,用于存储每个家庭作业的学生成绩,我希望能够存储成绩以及该学生获得certin成绩的次数,例如学生获得了A+ 30 times ,每个学生的年级,以及学生的成绩等级。一个档次的值是多少,例如A is worth 4.3MySQL评级数据库结构

所以我想知道什么是建立我的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 

回答

1

很多人会建议你有一个学生表,等级表和涉及学生和等级表的一个表格。然后,您可以根据将两者与程序关联的表格进行计数。许多人认为,在同一个表中有一个年级和一个学生是糟糕的关系设计。

+0

我确实有一张学生表和年级表以及一张将他们两者联系起来的表格。 – teach 2010-01-08 02:11:25

+0

那么我的桌子应该怎么样呢? – teach 2010-01-08 02:13:07

+0

基本数据: 学生表{id,name,<其他人口统计数据} 年级表{id,grade,fk_points} 关系表{id,fk_student,fk_grade} Point Table {id,point } – decompiled 2010-01-08 02:31:59

1

除非你想使用一个视图,在这种情况下真的不是必需的,否则你不会存储学生获得某个等级的次数;相反,当你需要的时候,你会做一个查询给你每个学生的信息。使用当前的模式,其中一个例子,告诉你多少次ID为st_id了每个年级一个特殊的学生,会像

SELECT COUNT(1) FROM grades WHERE student_id = st_id GROUP BY grade

这会看看那里的学生st_id得到了各等级和计数所有行他们分开。

只要存储从字母等级到其值的点数的映射,您可以执行以下两件事之一 - 要么具有从字母等级到点数量的表格映射,要么直接存储点数量。就我个人而言,我认为前者更清洁一点,因为它允许您在比例变化时更改积分量(而不是经常发生这种情况)。

除此之外,我认为你做得很好。我要说的唯一的事情是,如果在等级和工作之间始终存在一对一的映射关系,我可能会将工作表的成绩纳入工作表,而不是将其分开。也就是说,只有在等级表中没有不属于工作表的信息的情况下。

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

看看你的表,看起来有一些规范化,你可以做,或者我可能会误解客观。我假设学生和工作项目只有一个等级相关,这会使您的成绩基本上成为一个交叉参考表。因此,您不会在工作表中引用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可能会有所不同),但任何可以处理非整数数字的类型都可以工作。通过这种设计,您可以根据需要提取查询以获取所需的输出类型。

乔希

+0

有趣,因为我会走另一条路。通过工作让学生通过工作评分对我来说更直接(事实上,在工作分级之前在你的模式中发生了什么),但我必须说,多年的面向对象已经枯萎了我的能力关系思维。 – CurtainDog 2010-01-08 04:05:01

1

假设 -

  1. 有不止一个学生

  2. 有不止一个分配/件工作要针对

  3. 多个学生分级可以完成一套具体的工作/任务
  4. 只有一个年级可以赚取编按分配

我一起去 -

  1. 表中每一套作品/特定任务的定义。

  2. 一个表来定义每个学生

  3. 第三个表来记录每个学生每次分配的结果,即存储每个分配档次。

如 -

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 Server的人,所以这可能不是100%符合mysql(我没有测试过),但类似的东西会做我的想法。

如果您想进一步标准化数据,也可以将等级描述/值分解到另一个表中,或者仅根据存储的值在应用程序中显示等级描述(例如等级值4.5始终显示为“ A“等)