需要建议来改变我的数据库设计

时间:2010-06-14 16:42:36

标签: php sql mysql database-design data-structures

我需要改变我在数据库中存储信息的方式。因为查询对我开发的旧模型运行缓慢。
一般问题如下。
1)我有课程列表,每个课程都有描述课程一般内容的标签列表。例如,名为“数据库管理系统”的课程可以包含以下标记{ sql,index,key,relation }。
2)我的教授也有标签,这些标签通常描述了他们在课程中教授的内容。例如,Barton {sql,php,apache,mysql}
我需要找到DB中与所选课程最匹配的所有教授。另外,我需要根据匹配的重量对它们进行排序。
问题
问题是如何将此信息存储在数据库中以及如何处理此存储的信息以解决此问题。 在我收到关于我的SQL查询here的许多否定批评之后出现了这个问题。

4 个答案:

答案 0 :(得分:4)

好吧,我会从这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,可能不是那样:))

答案 1 :(得分:3)

听起来你应该有以下表格:

  • Course - 列出课程。
  • Subject_area - 课程可以涵盖的科目列表,例如“sql”,“c ++”等。
  • Course_content - CourseSubject_area之间的交叉引用表。
  • Professor - 列出教授。
  • Professor_expertise - ProfessorSubject_area之间的交叉引用表。

例如,您可能有一位名为“布朗教授”的教授,在表Professor中有相应的行,还有一个名为“sql”,“java”和“优化算法”的主题区域,每个教授都是教授布朗很感兴趣。然后Professor_expertise中每个区域都有一个相应的行,每个区域都会引用表格Professor中的布朗教授的行,以及表Subject_area中的相应行。 {1}}。

现在假设你有一门课程“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号。

答案 2 :(得分:1)

以下是我建议的架构(主键加粗):

  • 课程表: id name
  • 教授表: id name
  • 标签表: id name
  • courseTags: tag_idcourse_id tag_id上的索引可加快查询速度)
  • profTags: tag_idprof_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;

此查询返回一个教程ID列表,按照他们拥有的标记匹配数排序。

答案 3 :(得分:0)

在最简单的形式中,我建议有5个表:

tbl_CourseList

CourseId - int,PK,identity

CourseName - varchar(100)

tbl_CourseContent

ContentId - int,PK,identity

CourseId - int,FK

类型 - varchar(25)

tbl_Professors

ProfessorId - int,PK,identity

ProfessorName - varchar(100)

tbl_ProfessorExpertise

ExpertiseId - int,PK,identity

ProfessorId - int,FK

ExpertiseType - varchar(25)

ExpertiseWeight - int

tbl_ProfessorCourses

CourseId

ProfessorId

希望这是不言自明的......