我应该创建两个表来存储对象的特定信息吗?

时间:2012-11-19 16:43:19

标签: database database-design

我有一些表:

  • 课程:包含有关课程的信息,一门课程 has many 主题。
  • 主题:包含有关主题的信息,一个主题 belongs to 一个课程和一个主题 has many 问题。
  • 问题:包含有关问题的信息,一个问题 belongs to 一个主题。
  • GeneralExam:包含有关课程考试的信息,一门普通考试 belongs to 一门课程。
  • GeneralQuestion:包含常规考试的设定问题。

这是两个表的列:

  • GeneralExam:名称,描述,学期,持续时间,user_id,course_id,used(boolean),number_question
  • GeneralQuestion:general_exam_id,question_id

GeneralExam的问题是随机的。这意味着我将根据每个主题的具体问题数量得到随机问题。

现在我想知道一般考试的具体信息,例如课程中每个主题的问题数量,这些问题都是普通考试。目前,我想我会创建一个新表来存储该信息,例如:

  • 新表:general_exam_id,topic_id,number_question

但我不知道这是否是最佳方式,或者在这种情况下,还有其他方法或模式可以解决。因为如果我创建新表,当我在GeneralExam表中进行更改(例如:更改集问题)时,我将需要更新3表:GeneralExam,GeneralQuestion,New table。我不确定这是好方法。

所以我想问一下,我是否应该创建新表来存储该信息(一般考试中每个主题的问题数量),

或者我是否需要在表GeneralQuestion中对常规考试的商店信息进行一些更改,以及我应该做些什么更改?感谢您的任何建议和意见。

2 个答案:

答案 0 :(得分:1)

如果可以从当前数据查询所需信息,通常您应将其存储在另一个表中。原因是:每次从其他表添加/删除行时,您都必须更新此行。以这种方式创建数据不一致很容易。

对于您的示例(考试中给定主题的问题数量),您可以使用聚合轻松检索该信息:

select q.topic_id, count(gq.question_id)
from topic t join question q          on t.id = q.topic_id
             join general_question gq on q.id = gq.question_id
where gq.general_exam_id = 10
group by q.topic_ic;

OTOH如果你要存储的数据可以从其他数据中推断出来,那么是的,最好将它存储在有意义的地方 - 如果它特定于对{{1然后在一个表中将这两个值作为其candidate key(就像你在问题中建议的那样)。无论是创建新表还是在现有表中添加这些列(当然都使用正确的候选键),这是您的选择,我没有任何论据支持或反对这样做。

答案 1 :(得分:1)

我们试图说,创建一个新的额外表不需要。您希望通过对表的最小接触来有效地管理架构。

设计规则:

不应该将特定课程书中的编号主题与主题表的ID号混淆。课程不一定属于考试。这是必须属于课程的考试。到目前为止,您的设计已经正确无误。我假设您在GeneralQuestion表中存储了考试的所有问题,该表类似于过去考试的问题库(包括在不久的将来的日程考试,只允许访问考试版主)。

将GeneralQuestions表重命名为ExamsQuestions更有意义。通过该银行,您的设计会产生两种虚拟问题类型:来自银行的考试问题和问题表中的问题,其中考试问题引用了您的问题表。这样就可以为考试题库提供所需的参考密钥。在我看来,这是一个历史表。看来,您最终的表格,您不确定应该只是一个存储查询提供实时数据。

主要问题:您是否计划存储每个过去/预定的未来考试题?你说是的。因此,

日期根据我提供的设计成为您考试表中非常重要的一栏。你需要Date&考试表中的课程ID。

以下是我建议表格架构的方法。

tblCourse

ID,课程

ID  NAME
b105    biology 1st year
c323    chemistry 1st year
e120    english 1st year
m122    maths 1st year
m250    maths 2nd year
p302    physics 3rd year

tblTopic :虽然ID是索引编制,但CID识别主题的父级(课程)

ID,CID,主题

ID  CID     NAME
t1  m122    Algebra
t2  m122    Probability
t3  e120    Essay Writing
t4  p302    Optics
t5  b105    liver system
t6  b105    neural system
t7  p302    mechanics

tblQuestion :虽然ID是索引,但TID是识别问题的父级(主题)的原因

ID,TID,问题

tblExam:虽然ID是索引编制,但CID是识别问题的父母(课程)的原因

ID, CID, Exam, Date

ID  TID     QUESTION
q1  t2  x
q10 t7  p
q11 t4  n
q12 t6  i
q13 t7  r
q14 t6  k
q2  t1  y
q3  t1  z
q4  t2  a
q5  t2  v
q6  t6  s
q7  t6  h
q8  t1  l
q9  t2  g

tblExamsQuestions:外键:考试ID,问题ID

ID,QID

ID  CID     EXAM    DATE
e1  b105    1st Year Biology Main Stream    June, 08 2012
e2  m122    1st Year Maths Elective     December, 20 2011
e3  b105    1st Year Biology Main Stream    February, 10 2012

应用: 有人想获得去年第一年数学课程的考试问题。你怎么查询?如果考试ID是自动增量,那么很难知道哪个ID是什么考试。所以在这里你可以搜索一下特定课程考试的问题,只有考试的课程编号和日期。那应该做的 - >除非在同一天多次举行相同的课程考试。然后您也可以按时间保存数据。您可以删除日期,时间,只要您将考试表设计更改为通过考试ID查询,其中ID是正确的考试ID,而不仅仅是1,2,3 ......

课程ID = m122 日期=去年/月/日

这些是最符合逻辑/重要性的细节,可用作 COMPOSITE SEARCH KEY ,您需要从Exam表中查找考试ID,并在ExamsQuestions银行中使用它来提取考试题。

select * from question
where id in (
select eq.qid from examsquestions eq 
inner join exam e 
on e.id = eq.id
where e.date = '2011-12-20'
and e.cid = 'm122');

ID  TID     QUESTION
q1  t2  x
q5  t2  v
q7  t6  h

顺便说一下,因为你在考试中随机选择问题 - 如果我必须参加考试,我会非常担心。因为从一个主题获得所有问题的风险非常大。无论如何,这是一个侧面问题,我希望你有一个无偏见的 FAIR 机制来从课程的所有主题中生成考试;)

如果你有进一步的疑虑,请跟我说。任何人都应该提出一些建议,以改善更好的解决方案。

PS:很抱歉迟到的回复。