我目前正在使用PHP / MySQL开发调查创建/管理Web应用程序。我已经经历了数据库表的几个修订,我再次发现我可能需要重新考虑某种类型答案的存储。
现在,我有一个看起来像这样的表:
survey_answers
id PK
eid
sesid
intvalue Nullable
charvalue Nullable
id =分配给每一行的唯一值
eid =调查问题,这个答案是回复
sesid =调查'会话'(有关调查时间和日期的信息)id
intvalue =答案的值,如果它是一个数值
charvalue =答案的值,如果它是文本表示
这使我能够继续使用MySQL的数学函数来加速处理。
然而,我发现了一个新的挑战:存储有多个回复的问题。 一个例子是:
您喜欢吃以下哪种食物? (选择所有申请)
现在,当我想存储结果时,我不确定处理它的最佳方法。 目前,我有一个表格可供选择,如下所示:
survey_element_options
id PK
eid
value
id =与每行相关联的唯一值
eid =此选项与
关联的问题/元素value =该选项的文本值
通过此设置,我将返回的多个选择答案存储在'survey_answers'中,作为在调查中选择的element_options行的逗号分隔ID的字符串。 (例如“4,6,7,9”之类的东西)我想知道这是否确实是最好的解决方案,或者如果创建一个能够容纳每个答案的新表更为实际,然后再参考给定的答案行反过来引用回到元素并最终引用调查。
修改
对于任何有兴趣的人,这是我最终采取的方法(在PhpMyAdmin Relations View中):
收集多选问题的计数的基本查询将如下所示:
SELECT e.question AS question, eo.value AS value, COUNT(eo.value) AS count
FROM survey_elements e, survey_element_options eo, survey_answer_options ao
WHERE e.id = 19
AND eo.eid = e.id
AND ao.oid = eo.id
GROUP BY eo.value
答案 0 :(得分:4)
这真的取决于很多事情。
作为一个简单的例子,这可能会稍微复杂一些:
示例表:
Users
(Username
,UserID
)Questions
(qID
,QuestionsText
)Answers
(AnswerText
[在这种情况下示例可以重复使用,但这确实会造成额外的复杂层],aID
)Question_Answers
([此问题的可用答案,每个问题多个条目] qaID
,qID
,aID
),UserQuestionAnswers
(qaID
,uID
)注意:仅作为示例,而不是推荐
答案 1 :(得分:0)
将主键转换为非唯一索引,并在相同的ID下为同一问题添加答案。
例如。
id | eid | sesid | intval | charval
3 45 30 2
3 45 30 4
如果需要,您仍然可以为常规唯一PK添加另一列。
保持简单。这里不需要关系。
答案 2 :(得分:0)
真的是课程的马匹。
您可以存储为逗号分隔的字符串(但是当您在其中一个答案中使用文字逗号时会发生什么情况。)
您可以存储为一对多表格,例如:
survey_element_answers
id PK
survey_answers_id FK
intvalue Nullable
charvalue Nullable
然后遍历该表。如果您选择了一个答案,则会在此表中创建一行。如果您选择两个答案,它将在此表中创建两行,等等。然后,您将从survey_answers表中删除intvalue和charvalue。
另一个选择,因为你已经在他们自己的表中存储元素选项,就是创建一个多对多表,例如:
survey_element_answers
id PK
survey_answers_id FK
survey_element_options_id FK
同样,每个选项选择一行。
另一种选择是存储位掩码值。这将消除对多对多表的需求。
survey_element_options
id PK
eid FK
value Text
optionnumber unique for each eid
optionbitmask 2 ^ optionnumber
optionnumber对于每个eid应该是唯一的,并且从1开始递增。如果使用bigint,则将限制63个选项;如果使用int,则将限制为31个选项。
然后在 survey_answers
中id PK
eid
sesid
answerbitmask bigint
Answerbitmask是通过为用户选择的每个选项添加所有optionbitmask来计算的。例如,如果7存储在Answerbitmask中,则表示用户选择了前三个选项。
联接可以通过以下方式完成:
WHERE survey_answers.answerbitmask& survey_element_options.optionbitmask> 0
所以是的,还有一些选择需要考虑。
答案 3 :(得分:-1)
如果您不在另一个查询中将id用作外键,或者您可以使用sesid查询结果,请尝试多对一关系。 否则,我会将多选答案存储为序列化数组,例如JSON或通过php的serialize()函数。