2009-04-08 23 views
5

我正在创建一个Access数据库,用于在学校的C#应用​​程序中使用。我没有太多的经验与DB的工作,所以如果这听起来很愚蠢只是忽略它。我希望用户能够选择全部某个学生在我们的IT部门拥有的课程。我们大约有30个人,一个人可以在4年的高中中学到的最高分数是15.现在我的数据库有15个不同的列,每个班级可以有一个用户。我如何将它压缩到一列(如果有方法)?如何摆脱数据库中的多列?

回答

18

很好的问题,卢卡斯,这再往行为的数据库规范化。

事实上,你认识到为什么有多列表示类是不好的,这已经表明你有很大的潜力。

如果我们想添加一个新类,该怎么办?现在我们必须添加一个全新的专栏。这很少有灵活性。

那么可以做些什么?

我们创建了三个表格。

一个表,让学生:

Student 
    |-------------------------| 
    | StudentID | Student_Name| 
    |-------------------------| 
    |  1  |  John | 
    |  2  |  Sally | 
    |  3  |  Stan | 
    --------------------------- 

一个表是类:

Class 
    ------------------------ 
    | ClassID | Class_Name| 
    ------------------------ 
    | 1  | Math | 
    | 2  | Physics | 
    ------------------------ 

最后,一个表保存学生和类之间的关系:

Student_Class 
    ----------------------- 
    | StudentID | ClassID | 
    ----------------------- 

如果我们想要将John注册到Physics中,我们会在Student_Class表中插入一行。

INSERT INTO Student_Class (StudentID, ClassID) VALUES (1, 2); 

现在,我们有一个记录,说学生#1(约翰)正在参加第2课(物理)。让莎莉参加数学,斯坦参加物理和数学。

INSERT INTO Student_Class (StudentID, ClassID) VALUES (2, 1); 
    INSERT INTO Student_Class (StudentID, ClassID) VALUES (3, 1); 
    INSERT INTO Student_Class (StudentID, ClassID) VALUES (3, 2); 

要扳指回数据以可读的方式,我们加入了三个表一起:

SELECT Student.Student_Name, 
     Class.Class_Name 
    FROM Student, 
     Class, 
     Student_Class 
    WHERE Student.StudentID = Student_Class.StudentID 
     AND Class.ClassID = Student_Class.ClassID; 

这就给我们一个结果集是这样的:

------------------------------ 
    | Student_Name | Class_Name | 
    ------------------------------ 
    | John  | Physics | 
    | Sally  | Math  | 
    | Stan  | Physics | 
    | Stan  | Math  | 
    ------------------------------ 

这数据库规范化是如何工作的。

+0

优秀的回应。除了(有价值的,正确的)信息外,我还会补充一点,你可以存储关于所采用类的附加数据。如果你的数据库对组织有用,它将在晚些时候得到增强。这种设计可以实现这一点。可以添加年级,辅导员,结果等。 – Karl 2009-04-08 22:59:16

+0

感谢恭维,但老实说,我无法忍受横向卷动15级。你的回答确实有帮助,现在我开始阅读关于规范化的文章。我想在你的设计的帮助下,我可以为我的老师制作一个体面的应用程序(她实际上会使用它)。 – Kredns 2009-04-09 01:47:58

1

如何在学生表中没有任何班级列。使用学生ID和班级ID列设置一个新表。每一行代表学生所学的一门课。也许添加更多列,如:年/学期,等级等。

+0

你能解释这多一点点,我不完全遵循。 – Kredns 2009-04-08 21:22:21

4

听起来好像你需要考虑一下normalizing你的数据库模式。

学生和班级之间有many-to-many relationship,这样许多学生可以上很多班,很多学生可以上很多班。处理这种情况的最常见方法是使用junction table

像这样的事情

Student Table 
------------- 
id 
first_name 
last_name 
dob 

Class Table 
----------- 
id 
class_name 
academic_year 

Student_Class Table 
------------------- 
student_id 
class_id 
year_taken 

然后你的查询将加入在桌子上,例如,建议

SELECT 
    s.last_name + ', ' + s.first_name AS student_name, 
    c.class_name, 
    sc.year_taken 
FROM 
    student s 
INNER JOIN 
    student_class sc 
ON 
    s.id = sc.student_id 
INNER JOIN 
    class c 
ON 
    sc.class_id = class.id 
ORDER BY 
    s.last_name, sc.year_taken 

一个字,我会提的是,Access,需要使用括号时在查询中加入多个表格,我相信这是因为它要求您指定加入它们的顺序。就我个人而言,我觉得这很尴尬,尤其是当我习惯于在没有设计师的情况下编写大量的SQL时。在Access中,我建议使用设计器来连接表,然后修改生成的SQL以达到您的目的。

4

所以你有15列(例如class1,class2,class3 ... class15)?

看起来像你有一个经典many-to-many relationship。你应该创建一个新表来关联学生和班级。

student { StudentID, StudentName ... } 
classes { ClassID, ClassName ... } 
student_classes { StudentID, ClassID } 

如果您在一年的按年计算的跟踪类,你可能在一年列添加到关系以及:

student_classes { StudentID, Year, ClassID } 
2

这是一个标准化问题。实际上你问的是错误的问题。而是问自己这个问题,你怎么能存储0个或更多classes_taken?你需要针对每个班级存储哪些其他细节?例如。只是所采取的课程,或采取的数据,结果等?

例如,考虑事端像下面

 
table Student 
id int 
name varchar(25) 
... 

table classes 
id int 
name varchar(25) 
... 

table clases_taken 
student_id int (foreign key to student.id) 
class_id int (foreign key to class.id) 
data_started datatime 
result varchar(5) 
tutor_id int (foreign key to tutor.id) 
... 

2

你不应该有这样的Class1,Class2中,CLASS3,CLASS4等列在数据库表中。你应该有一个相关的表格。你stucture会是这样的:

Student Table with the following columns 
StudentID 
StudentLastName 
StudentFirstName 
(and so forth for all the data to describe a student) 

然后

Course table with the following columns 
CourseId 
CourseName 

然后

StudentCourse Table with the following columns 
StudentId 
CourseID 
CourseDate 

我们找出课程的人把你加入这些表连接在一起。 喜欢的东西:

Select StudentID,StudentLastName,StudentFirstName, CourseName, CourseDate 
from Student 
join StudentCourse on student. studentid = StudentCourse.StudentID 
join Course on Course.courseID = StudentCourse.CourseID 

请阅读此链接开始学习数据库基本面: http://www.deeptraining.com/litwin/dbdesign/FundamentalsOfRelationalDatabaseDesign.aspx