Нужен совет, чтобы изменить мой дизайн базы данных - PullRequest
0 голосов
/ 14 июня 2010

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

Ответы [ 4 ]

4 голосов
/ 14 июня 2010

Ну, я бы начал с чего-то вроде этих 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, вероятно, не то:))

3 голосов
/ 14 июня 2010

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

  • 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 - идентификационный номер, соответствующий курсу.

1 голос
/ 14 июня 2010

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

  • таблица курсов: 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;

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

0 голосов
/ 14 июня 2010

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

tbl_CourseList

CourseId - int, PK, identity

CourseName - varchar (100)

tbl_CourseContent

ContentId - int, PK, identity

CourseId - int, FK

Тип - varchar (25)

tbl_Professors

ProfessorId - инт, ПК, личность

ProfessorName - varchar (100)

tbl_ProfessorExpertise

ExpertiseId - int, PK, идентификационный номер

ProfessorId - int, FK

ExpertiseType - varchar (25)

ExpertiseWeight - int

tbl_ProfessorCourses

CourseId

ProfessorId

Надеюсь, это говорит само за себя ...

...