Курсы моделирования и пререквизиты в базе

Базовый сценарий: у меня есть студенты, курсы и требования к курсам, которые необходимо хранить в базе данных.

Кто-нибудь знает, как лучше всего хранить эти и проходить предварительные условия курса?

1) Простой пример:

  • C: Математика 100, требование: нет
  • C: Math 150, требования: нет
  • C: Математика 200, предварительное требование: Математика 101, Математика 150

Учащийся А закончил Math 100. Как определить, имеет ли он право сдавать CS200 с помощью запросов к базе данных?

2) Более сложный пример:

  • C: Chem 100, требования: нет
  • C: Химия 200, предварительное требование: Химия 100
  • C: Химия 201, предварительное требование: Химия 200
  • C: Химия 202, предварительное требование: Химия 200
  • C: Chem 300, предварительное требование: любые два из Chem 200, Chem 201, Chem 202

Учащийся Б завершил Химию 100, Химию 200, Химию 203. Как проверить, имеет ли он право сдавать Химию 300?

Как смоделировать иерархию предпосылок в базе данных? Любые советы, ссылки, ссылки будут приветствоваться.


person Swartz    schedule 10.11.2010    source источник
comment
Шварц. Вам нужно прочитать свои ответы и ответить.   -  person PerformanceDBA    schedule 25.11.2010


Ответы (2)


Есть несколько вещей, о которых вы не подумали, например, о сущностях, которые необходимо определить, которые подразумеваются в вашем вопросе. Позвольте мне включить несколько, но не отвлекайтесь на них, я сосредоточусь на поставленном вами вопросе. Вы можете спокойно игнорировать Grade, Teacher и т. д. сейчас и подумать о них в будущем.

Типичная модель данных для колледжа

Нотация IDEF1X для тем, кто нуждается в объяснении символов.

  • Нет необходимости добавлять суррогатные ключи, если они не требуются, поскольку естественный ключ становится слишком большим для переноса в дочерние элементы; Я не слепо штамповал их как PK на каждом столе. В любом случае рассмотрение идет на физическом, а не логическом уровне.

  • Однажды я смоделировал RDb для местного университета. Я думаю, что в дополнение к предварительным требованиям, таким как "любые два из...", вам может понадобиться "и хотя бы один из...", поэтому я предусмотрена любая их комбинация.

  • Requisite содержит полный список возможных реквизитов

    • IsMandatory указывает, что Реквизит является обязательным для выполнения "хотя бы одного из..."; остальные нет и попадают в "любые два из..."

    • Grade позволяет указать минимальный уровень в качестве обязательного.

  • Course.NumRequisite указывает количество возможных Requisites, которые требуются, например, "любые два из ..."

Если вам нужен код SQL для навигации по структуре, пожалуйста, спросите.

person PerformanceDBA    schedule 11.11.2010
comment
Спасибо за информацию, размещение кода SQL очень помогло бы, особенно при обработке случаев по крайней мере одного из и любых двух из. В частности, у меня есть вопрос, касающийся этого, я был бы очень признателен, если бы вы могли его посмотреть (stackoverflow.com/questions /21519140/). Спасибо - person lberezy; 10.02.2014

Я думаю, что следующее сделает большую часть того, что вы хотите:

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), но это должно быть полезно для начала. Или, цитируя философа Пратчетта

Не тестируется на животных — вы будете первыми!

Делитесь и наслаждайтесь.

person Bob Jarvis - Reinstate Monica    schedule 10.11.2010