基于类型的数据库设计

3
我想给学生和老师评分(很好,好,一般,差等等)。哪种设计方案更好呢? 方案1:

学生(StudentID, 评级,...)

-----------------1--------好-----

-----------------2--------差-----

-----------------3-----很好-----


老师(TeacherID, 评级,...)

-----------------1-----很好-----

-----------------2--------差-----

-----------------3--------差-----

方案2:

学生(StudentID, 评级类型ID,...)

-----------------1----------------2----------

-----------------2----------------1----------

-----------------3----------------3----------


老师(TeacherID, 评级类型ID,...)

-----------------1----------------1----------

-----------------2----------------1----------

-----------------3----------------3----------


评级类型(评级ID, 评级描述,...)

-----------------1-------------很好---------

-----------------2---------------好--------------

-----------------3----------------差---------------


如果这两种方案都不够好,请您给出建议。谢谢!
2个回答

2
方案2是这两个方案中最好的,但如果您希望在应用程序的生命周期内进行多次投票,您应该拥有一个表格,其中您可以识别投票主题,另一个表格则存储投票结果。
Student:
   id
   name
   class
   ...

Teacher:
   id
   name
   subject
   ...

voterType
   id 
   description (student or teacher)

contest:
   id
   description (ex: 1st Semester 2013)

contestVotes:
   id
   contestId
   voterType (Teacher or Student)
   voterId
   ratingTypeId

谢谢您的回答。我有一个关于您的设计的问题:contestVotes表。如果我想获取有关投票者的更多信息,我必须检查voterType(教师或学生)并加入相应的表格(教师或学生)吗?我如何使用MySQL实现这一点? - Jack Cood
1
如果您想直接选择选民类型为学生的记录,可以使用内连接(inner join)与学生表进行关联,并从中获取信息。如果您想获取关于学生和教师的信息,可以使用内连接(inner join)ON contestVotes..voterID = student.id AND contestVotes.voterType = 1(student),同样适用于教师。这回答了您的问题吗?还是我误解了您的问题? - Filipe Silva
我的意思是我想获取有关contestVotes.id = 1的选民信息(例如)。当然,我不知道选民的类型,我只知道输入的一个东西是contestVote ID - Jack Cood
这取决于您想在学生/教师中获得什么信息。通常,您想在像contestVotes这样的表格中了解的是有多少教师/学生投票以及投票内容。如果您想同时从不同的学生和教师表格中获取信息,则必须创建一种输出两个信息并且有意义的方式。 - Filipe Silva

1
在这两种解决方案中,我肯定会选择第二种,原因如下:
  • 将“评分”存储为数字可以在需要排序或聚合的情况下派上用场,在这种情况下,字符串几乎没有用处。

  • 将“评分”列作为“RatingType.RatingID”的外键强制执行约束,即“评分”只能具有非常特定的一组值和非常特定的含义。此外,您还可以在将来向“RatingType”表添加额外列,从而增加评分的价值。

关于改进建议,既然你问了,考虑使用IS-A relations来实现。老师和学生都是Persons,在某种程度上有共同的属性。我会创建一个包含共同属性(即名字、姓氏、地址、电话等)的Person超类表,然后使studentsteachers的主键也成为Persons的外键。
请注意,评分也是一个共同的属性。因此,在Persons表中出现是很自然的。除非老师和学生有不同类型的评分,那么您需要实现两个不同的RatingType表。

谢谢您的回答。我有一个关于性能的问题:如果我选择“解决方案2”,我必须使用joinRatingTypeTeachersRatingTypeStudents)来获取所有信息,所以如果RatingType表包含非常少的行,而StudentsTeachers表非常大,那么在使用join操作时的成本性能会很昂贵吗? - Jack Cood
在这种情况下,您将需要首先在“学生”和“教师”之间执行“联合”,然后再将结果与“RatingType”连接。这就是为什么我提出了IS-A方法,其中大多数时间您只需要将“人”与“RatingType”连接。当然,“人”甚至更大,但使用正确的“索引”,性能应该不是您问题的主要原因。 - geomagas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接