【问题标题】:Need advice to change my database design需要建议来更改我的数据库设计
【发布时间】:2011-03-03 14:48:21
【问题描述】:
我需要更改在数据库中存储信息的方式。因为查询在我开发的旧模型上运行缓慢。
一般问题如下。
1) 我有课程列表,每门课程都有描述课程一般内容的标签列表。例如,名为“数据库管理系统”的课程可能有以下标签{sql、index、key、relation}。
2) 我的教授也有标签,这些标签通常描述他们在课程中教授的内容。例如,巴顿 {sql, php, apache,mysql}
我需要找到数据库中与特定所选课程最匹配的所有教授。我还需要按它们的匹配权重对它们进行排序。
问题
问题是如何将这些信息存储在数据库中以及如何处理这些存储的信息以解决这个问题。
这个问题是在我收到很多关于我的sql查询here的负面批评之后出现的。
【问题讨论】:
标签:
php
sql
mysql
database-design
data-structures
【解决方案1】:
好吧,我将从这 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,可能不是那样:))
【解决方案2】:
听起来你应该有以下表格:
-
Course - 列出课程。
-
Subject_area - 课程可以涵盖的主题列表,例如“sql”、“c++”等。
-
Course_content - Course 和 Subject_area 之间的交叉引用表。
-
Professor - 列出教授。
-
Professor_expertise - Professor 和 Subject_area 之间的交叉引用表。
例如,您可能有一个名为“Prof. Brown”的教授,在表Professor 中有相应的行,还有名为“sql”、“java”和“优化算法”的学科领域,每个领域都是 Brown 教授感兴趣。那么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号。
【解决方案3】:
这是我建议的架构(主键加粗):
- 课程表:
id和name
- 教授表:
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;
此查询返回一个教授 ID 列表,按他们拥有的标签匹配数排序。
【解决方案4】:
在最简单的形式中,我建议有 5 个表格:
tbl_CourseList
CourseId - 整数、PK、身份
课程名称 - varchar(100)
tbl_CourseContent
ContentId - 整数、PK、身份
CourseId - int, FK
类型 - varchar(25)
tbl_Professors
ProfessorId - int、PK、身份
教授姓名 - varchar(100)
tbl_ProfessorExpertise
ExpertiseId - 整数、PK、身份
ProfessorId - int, FK
ExpertiseType - varchar(25)
ExpertiseWeight - int
tbl_ProfessorCourses
课程编号
教授编号
希望这是不言自明的......