9

我目前正在使用 PHP/MySQL 进行调查创建/管理 Web 应用程序。我对数据库表进行了几次修改,我再次发现我可能需要重新考虑某种类型答案的存储。

现在,我有一个看起来像这样的表:

调查答案

id          PK
eid
sesid
intvalue    Nullable
charvalue   Nullable

id = 分配给每一行的唯一值

eid = 此答案所答复的调查问题

sesid = 调查“会话”(有关调查时间和日期的信息)id

intvalue = 答案的值(如果是数值)

charvalue = 答案的值(如果它是文本表示形式)

这让我可以继续使用 MySQL 的数学函数来加快处理速度。

然而,我发现了一个新的挑战:存储具有多个响应的问题。一个例子是:

您喜欢吃以下哪一项?(选择所有申请)

  • 女童子军饼干
  • 熏肉
  • 玉米
  • 鲸脂

现在,当我想存储结果时,我不确定处理它的最佳方法。目前,我有一个表格,仅用于多项选择,如下所示:

调查元素选项

id        PK
eid
value

id = 与每一行关联的唯一值

eid = 此选项关联的问题/元素

value = 该选项的文本值

使用此设置,然后我将返回的多项选择答案存储在“survey_answers”中,作为调查中选择的 element_options 行的逗号分隔 ID 字符串。(即类似“4,6,7,9”)我想知道这是否确实是最好的解决方案,或者创建一个新表来保存每个选择的答案是否更实际,然后参考一个给定的答案行,它反过来引用元素并最终引用调查。


编辑

对于任何感兴趣的人,这是我最终采用的方法(在 PhpMyAdmin 关系视图中):

数据库关系和表结构

收集多选问题的计数的基本查询如下所示:

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
4

4 回答 4

6

这真的取决于很多事情。

  1. 通常,将逗号分隔值列表存储在数据库中是不好的,尤其是如果您计划对这些数据进行远程智能操作。特别是如果您想对答案进行任何类型的高级报告。
  2. 存储它的最佳关系方法是也在第二个表中定义答案,然后将它们链接到用户对第三个表中的问题的响应(每个用户问题有多个条目,或者可能是用户调查问题,如果用户可以针对同一个问题进行多项调查。

作为一个简单的例子,这可能会变得有点复杂:

示例表:

  • Users( Username, UserID)
  • Questions( qID, QuestionsText)
  • AnswersAnswerText[在这种情况下,示例可能是可重用的,但这也会导致额外的复杂性],aID
  • Question_Answers([此问题的可用答案,每个问题多个条目] qaID, qID, aID),
  • UserQuestionAnswers( qaID, uID)

注意:仅作为示例,而非推荐

于 2013-02-06T23:11:07.833 回答
2

将主键转换为非唯一索引,并在相同 id 下添加相同问题的答案。

例如。

id  | eid | sesid | intval | charval
 3     45      30        2  
 3     45      30        4

如果需要,您仍然可以为常规唯一 PK 添加另一列。

保持简单。这里不需要关系。

于 2013-02-06T23:09:18.627 回答
1

这真是一匹马的课程。

您可以存储为逗号分隔的字符串(但是当您的答案之一中有文字逗号时会发生什么)。

您可以存储为一对多表,例如:

调查元素答案

id                PK
survey_answers_id FK
intvalue          Nullable
charvalue         Nullable

然后循环遍历该表。如果您选择一个答案,它将在此表中创建一行。如果您选择两个答案,它将在此表中创建两行,依此类推。然后您将从survey_answers 表中删除 intvalue 和 charvalue。

另一种选择,因为您已经将元素选项存储在他们自己的表中,所以创建一个多对多表,例如:

调查元素答案

id                         PK
survey_answers_id          FK
survey_element_options_id  FK

同样,每个选项选择一行。

另一个选择是存储位掩码值。这将消除对多对多表的需要。

调查元素选项

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

对于用户选择的每个选项,通过将所有选项位掩码相加来计算答案位掩码。例如,如果 7 存储在 Answerbitmask 中,那么这意味着用户选择了前三个选项。

可以通过以下方式进行连接:

其中survey_answers.answerbitmask &survey_element_options.optionbitmask > 0

所以,是的,有几个选项需要考虑。

于 2013-02-06T23:16:21.563 回答
-1

如果您在另一个查询中不使用 id 作为外键,或者如果您可以使用 sesid 查询结果,请尝试多对一关系。否则,我会将多项选择答案存储为序列化数组,例如 JSON 或通过 php 的 serialize() 函数。

于 2013-02-06T23:09:02.723 回答