Нужен совет по изменению дизайна моей базы данных

Мне нужно изменить способ хранения информации в БД. Потому что запрос работает медленно с старой моделью, которую я разработал.
Общая проблема следующая.
1) У меня есть список курсов, и у каждого курса есть список тегов, описывающих общее содержание курса. Например, курс под названием «Системы управления базами данных » может иметь следующие теги: { sql, index, key, relation }.
2) У меня есть профессора, у которых есть теги, которые обычно описывают, чему они учат в своих курсах. Например, Barton {sql, php, apache, mysql}
Мне нужно найти всех преподавателей в БД, которые наилучшим образом соответствуют конкретному выбранному курсу. Также мне нужно отсортировать их по их весу соответствия.
Вопрос
Вопрос заключается в том, как хранить эту информацию в БД и как обрабатывать эту сохраненную информацию для решения этой проблемы.
Этот вопрос появился после того, как я получил массу негативных критических замечаний по поводу моего запроса sql здесь .

Ну, я бы начал с чего-то вроде этих 5 таблиц:

Course (CourseID, CourseName, ...) Professor (ProfID, ProfName, ...) Tag (TagID, TagName) CourseTag (CourseID, TagID) ProfTag (ProfID, TagID) 

и запросите его что-то вроде

 SELECT ProfName, Count(PT.TagID) AS Weighting FROM Professor P INNER JOIN ProfTag PT ON P.ProfID = PT.ProfID INNER JOIN CourseTag CT ON PT.TagID = CT.TagID WHERE CT.CourseID = @SelectedCourse GROUP BY ProfName 

Это синтаксис MS SQL Server … не знаю, что вы используете (но с php, возможно, не так :))

Похоже, вы должны иметь следующие таблицы:

  • Course – перечисляет курсы.
  • Subject_area – список тем, которые могут охватывать курсы, такие как «sql», «c ++» и т. Д.
  • Course_content – перекрестная справочная таблица между Course и Subject_area .
  • Professor – перечисляет профессоров.
  • Professor_expertise – перекрестная справочная таблица между Professor и Subject_area .

Например, у вас может быть профессор «Проф. Браун» с соответствующей строкой в ​​таблице « Professor , а также тематические области, называемые «sql», «java» и «алгоритмы оптимизации», каждый из которых интересуется профессором Брауном. для каждой из этих областей в Professor_expertise будет соответствующая строка, и каждый из них будет ссылаться на строку профессора Брауна в таблице Professor , а также соответствующую строку в таблице Subject_area .

Теперь предположим, что у вас есть курс «SQL и дизайн базы данных», и в нем есть области «Дизайн базы данных», «SQL», «Индексы базы данных», «Нормализация» и «Оптимизация запросов». Вы могли видеть, какие профессора подходят для обучения курсу, выпуская

 SELECT Professor.Name, Professor.Id, MySubquery.NumMatches FROM Professor JOIN ( SELECT Professor, COUNT(*) AS NumMatches FROM Professor_expertise WHERE Subject_area_id IN ( SELECT Course_content.Subject_area_Id FROM Course_content WHERE Course_content.Course_Id = x ) GROUP BY Professor ) AS MySubquery ORDER BY MySubquery.NumMatches DESC 

где x – идентификационный номер, соответствующий курсу.

Вот что я предлагаю в качестве вашей схемы (первичные ключи выделены жирным шрифтом):

  • таблица курсов: id и name
  • таблица profs: id и name
  • таблица тегов: id и name
  • courseTags: tag_id и course_id (индекс на tag_id для ускорения запроса)
  • profTags: tag_id и prof_id (индекс на tag_id для ускорения запроса)

Тогда вы можете так:

 SELECT profs.id, COUNT(*) AS matches FROM profs, profTags, courseTags WHERE profs.id=profTags.prof_id AND profTags.tag_id=courseTags.tag_id AND courseTags.course_id=[COURSE ID] GROUP BY profs.id ORDER BY matches DESC; 

Этот запрос возвращает список идентификаторов prof, упорядоченных по количеству совпадений тегов.

В простейшей форме я бы предложил иметь 5 таблиц:

 tbl_CourseList 

CourseId – int, PK, identity

Название курса – varchar (100)

 tbl_CourseContent 

ContentId – int, PK, identity

CourseId – int, FK

Тип – варчар (25)

 tbl_Professors 

ProfessorId – int, PK, identity

ProfessorName – varchar (100)

 tbl_ProfessorExpertise 

ExpertiseId – int, PK, identity

ProfessorId – int, FK

ЭкспертизаТип – варчар (25)

ExpertiseWeight – int

 tbl_ProfessorCourses 

CourseId

ProfessorId

Надеюсь, это самоочевидно …