【问题标题】:Modeling courses and pre-requisites in the database在数据库中建模课程和先决条件
【发布时间】:2010-11-10 21:23:52
【问题描述】:

基本场景:我有需要存储在数据库中的学生、课程和课程要求。

任何人都知道存储这些和遍历课程先决条件的最佳方式吗?

1) 简单示例:

  • C:数学 100,前提条件:无
  • C:数学 150,前提条件:无
  • C:数学 200,先决条件:数学 101,数学 150

学生 A 完成了数学 100。如何通过数据库查询确定他是否有资格参加 CS200?

2) 更复杂的例子:

  • C:Chem 100,前提条件:无
  • C:Chem 200,前提条件:Chem 100
  • C:化学 201,前提条件:化学 200
  • C:化学 202,先决条件:化学 200
  • C:Chem 300,前提条件:Chem 200、Chem 201、Chem 202 中的任意两个

学生 B 完成了 Chem 100、Chem 200、Chem 203。您如何检查他是否有资格参加 Chem 300?

如何对数据库中的先决条件层次结构进行建模?任何建议、链接、参考都将受到欢迎。

【问题讨论】:

  • 斯沃茨。您需要阅读答案并做出回应。

标签: sql database-design model


【解决方案1】:

在需要定义的实体中,您几乎没有考虑过一些事情,这些事情隐含在您的问题中。请允许我包括一些,但不要被他们分心,我专注于你提出的问题。您现在可以放心地忽略 Grade, Teacher 等,并在未来考虑它们。

Typical Data Model for a College

IDEF1X Notation, 给那些需要解释符号的人。

  • 除非需要,否则无需添加代理键,因为自然键太大而无法携带到子项中;我并没有在每张桌子上盲目地将它们标记为PK。无论如何,考虑是在物理层面,而不是逻辑层面。

  • 我曾经为当地一所大学建模了一个 RDb。我认为除了诸如“任意两个...”之类的先决条件之外,您可能还需要“和至少一个...”,所以我有提供这些的任意组合。

  • Requisite 包含可能需要的完整列表

    • IsMandatory 表明满足“至少有一个...”的必要条件是强制性的;其余的都不是,并且落入“任意两个...”

    • Grade 允许将最低等级指定为必要条件 .

  • Course.NumRequisite 标识可能需要的 Requisites 的数量,如 "any two of ..."

如果您需要 SQL 代码来导航结构,请询问。

【讨论】:

  • 感谢您提供的信息,发布 SQL 代码会有很大帮助,尤其是处理“至少一个”和“任何两个”的情况。更具体地说,我有一个与此相关的问题,如果您能看一下,我将不胜感激(stackoverflow.com/questions/21519140/…)。谢谢
【解决方案2】:

我认为以下内容可以满足您的大部分需求:

Table COURSE
  ID_COURSE    NUMBER         PRIMARY KEY
  DESCRIPTION  VARCHAR2(200)

Table PREREQUISITE_COURSE
  ID_COURSE         NUMBER    REFERENCES COURSE.ID_COURSE
  ID_PREREQ_COURSE  NUMBER    REFERENCES COURSE.ID_COURSE
  PRIMARY KEY (ID_COURSE, ID_PREREQ_COURSE)

Table STUDENT
  ID_STUDENT        NUMBER    PRIMARY KEY

Table STUDENT_COURSE
  ID_STUDENT        NUMBER    REFERENCES STUDENT.ID_STUDENT
  ID_COURSE         NUMBER    REFERENCES COURSE.ID_COURSE
  COMPLETED         CHAR(1)   CHECK(IN('Y', 'N'))
  PASSED            CHAR(1)   CHECK(IS NULL OR IN ('Y', 'N'))

鉴于上述查询,以检查学生是否已成功完成所有课程作业以参加给定课程,如果编写查询以返回学生未参加的先决课程实际上会更容易 - 类似于

SELECT c.*
  FROM STUDENT s
INNER JOIN COURSE STUDENT_COURSE sc
  ON (sc.ID_STUDENT = s.ID_STUDENT)
LEFT OUTER JOIN PREREQUISITE_COURSE pc
  ON (pc.ID_PREREQ_COURSE = sc.ID_COURSE)
INNER JOIN COURSE c
  ON (c.ID_COURSE = pc.ID_COURSE)
WHERE s.ID_STUDENT = <id of student of interest> AND
      c.ID_COURSE = <id of course of interest> AND
      sc.COMPLETED = 'Y' AND
      sc.PASSED = 'Y' AND
      pc.ID_PREREQ_COURSE IS NULL

请注意,这还没有经过任何测试,可能包含一些可怕的逻辑错误(例如,我对 COURSE 表的后期连接有点怀疑)但它应该是有用的入门和。或者,引用哲学家普拉切特的话

未在动物身上进行测试 - 你会是第一个!

分享和享受。

【讨论】:

    猜你喜欢
    • 2014-10-20
    • 2021-03-05
    • 1970-01-01
    • 2023-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多