我正在开发一个用于质量控制检查清单的网络应用程序。我已经设置了一个表,但是我有一种预感,我们的模型是次优的,我可以获得更好的性能。请注意,我不是在使用mysql,所以我只限于它的功能。
每个清单都有数十个问题,有时还有数百个问题。每个问题都有2到10个可能的答案。每个问题都是一个varchar字符串,每个答案也是如此。完整的检查表是指所有问题都与其中一个可能的答案相关联 - 当选择一个答案时。
检查表因不同目的而有所不同,它们可能会随时间而变化。因此,为了防止在我们想要更新新清单时无意中更改已完成的清单,我们有模板。模板,问题和答案是清单,问题和答案的镜像,并代表清单的“当前版本”。
所以表层次结构看起来像这样
。客户
由于我们不希望当前模板中的更改“及时返回”并更改已完成的清单,因此当用户开始新的清单时,数据会从模板复制到检查清单。
你可以猜到,这会产生很多重复。在ChecklistQuestionAnswers中,在大约一百万个答案行中,只有4,000个不同的答案。当然,TemplatesQuestionAnswers也有重复,但并不坏。
所以我认为我想要做的是为清单模板创建一个版本控制系统,这样我就可以通过存储唯一一组答案的唯一问题来节省空间。这样,我可以将一个清单与一个模板的版本链接起来,而不是复制文本批发,然后一个清单集就是为哪个问题选择了答案。
这是我到目前为止所勾画的内容。
客户有很多模板。一个 模板有很多修订,但只有 一个当前的修订。每次修订 有很多问题,每个问题 有很多(2到10个)答案。 每个清单与一个清单有关 模板。每个清单都有一套 表明答案的答案 选择其中的每个问题 模板的版本。
Questions /* all unique question wordings */
Questions.id
Questions.question
Answers /* all unique answer wordings. */
Answers.id
Answers.answer
Templates
Templates.client_id /* relates to client table. */
Templates.template_name
Templates.current_version /* this is related to TemplateVersions.version_number */
TemplateVersions /* A logical grouping of a set of questions and answers */
TemplateVersions.version
TemplateVersions.template_id /* relates this version to a template. */
TemplateQuestions
TemplateQuestions.template_version /* relates a question to a template version */
TemplateQuestions.question_id /* relates a unique question to this template version */
TemplateQuestions.id
TemplateQuestionAnswers
TemplateQuestionAnswers.template_question_id /* relates this answer to a particular template version question */
TemplateQuestionAnswers.answer_id /* relates the unique question to a unique answer */
TemplateQuestionAnswers.id
Checklists
Checklists.id
Checklists.template_version /* relates this question to a template version -- associating this checklist to a client happens through this relationship */
ChecklistAnswers /* ( I might call this something other than 'Answers' since the lack of ChecklistQuestionAnswers breaks 'name symmetry' with TemplateQuestionAnswers ) */
ChecklistAnswers.checklist_id
ChecklistAnswers.question_id
ChecklistAnswers.answer_id
我正在忙着保证ChecklistAnswers关联一个正确的问答对 - 它是Checklist父引用的模板版本中存在的关系。
换句话说,ChecklistAnswers中的每一行必须将TemplateQuestions中的一个question_id“镜像”为一个来自TemplateQuestionAnswers的子问题,形成Checklists中的template_version。我正在考虑如何做到这一点,我的思维过程在这里短路。这实际上是数据库的“可交付成果” - 一个完整的清单 - 所以所有其他模板和所有内容都是一种附带的或者是抽象的。如果我不能让这个工作,我错过了重点!
这似乎是小笨重,所以我想知道我是否正在制作一个解决方案,其复杂性不值得我实现它可能节省的空间。
另请注意,我对此进行了简化。还有其他方面的复杂性,例如用于为报告分组问题的类别系统,但我认为我们不需要在此处进行讨论。
答案 0 :(得分:1)
据我所知:
您正在做的事情的一个简单改进可能是使用3个表格用于模板,而只有2个表格用于实际清单: 清单(使用的模板版本的外键) 答案(核对清单的外键,templateAnswer的外键)
因此,如果您想要检索特定清单的答案列表,您可以:
select <whatever columns you like>
from checklist c, answer a, templateAnswer ta, templateQuestion tq
where a.checklist_id = c.id AND a.ta_id = ta.id AND ta.tq_id = tq.id AND
c.id = <something>
PS。如果问题分享答案,并且他们可能在许多情况下都会这样做(“是”,“不”想到),您可以找到一个表格来获得独特的答案: templateAnswers和表templateAnswerUsage(模板答案的外键和templateQuestion的外键)。这样您就没有答案文本的重复。 问题和答案之间的关系基本上是多对多的。 这取决于答案平均大小是否大于您将使用的ID的大小,这可能有意义也可能没有意义。