【问题标题】:MySQL: Updating Lookup TablesMySQL:更新查找表
【发布时间】:2013-05-22 22:20:04
【问题描述】:

在我的调查问题 (s_questions) 和可能的答案 (s_option_choices) 数据库中,我有一个查找表 (s_question_options):

创建语法:

CREATE TABLE `s_question_options` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`questions_id` int(11) unsigned NOT NULL,
`option_choices_id` int(11) unsigned NOT NULL,
PRIMARY KEY (`id`),
KEY `questions_id` (`questions_id`),
KEY `option_choices_id` (`option_choices_id`),
CONSTRAINT `s_question_options_ibfk_1` FOREIGN KEY (`questions_id`) REFERENCES `s_questions` (`id`) ON DELETE NO ACTION ON UPDATE CASCADE,
CONSTRAINT `s_question_options_ibfk_2` FOREIGN KEY (`option_choices_id`) REFERENCES `s_option_choices` (`id`) ON DELETE NO ACTION ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=1790 DEFAULT CHARSET=utf8;

这样填充:

INSERT INTO s_question_options (questions_id, option_choices_id)
SELECT sq.id, so.id FROM s_questions sq
JOIN s_option_choices so
ON sq.option_groups_id = so.option_groups_id;

如果我用新的/更改的/删除的可能答案更新s_option_choices,什么语法将更新我的查找表s_question_options,以便当前问题可用但旧答案(存储在答案表中,并通过@987654326 引用@) 仍然被正确引用?

编辑

我可以通过以下方式将新问题或新 option_choices 添加到我的查找表中:

INSERT INTO s_question_options (questions_id, option_choices_id)
SELECT sq.id, so.id FROM s_questions sq JOIN s_option_choices so
ON sq.option_groups_id = so.option_groups_id
WHERE sq.id NOT IN (SELECT questions_id FROM s_question_options)
OR so.id NOT IN (SELECT option_choices_id FROM s_question_options)

它与最初用于填充查找表的选择查询相同,但条件是 a) 以前没有输入过输入的问题,或者 b) 以前没有输入过 option_choice。

更改 option_choices 不应该是一项要求,它没有任何意义,并且在参照完整性游戏中没有地位。

删除 option_choices 可以通过我的答案表外键 (id) ON DELETE SET NULL 来解决。这实际上会将带有已删除 option_choice 的问题的答案设置为 NULL,并且在我的应用程序中,我可以查找此问题并采取相应的行动(问题未得到回答,或使用现在不相关的数据回答)。

正如建议的那样,还可以在 option_choices 表(甚至应用程序中的 option_choices 数组)中设​​置一个显示标志,以防止这些 option_choices 在表单中显示,但仍将数据保留在数据库中。

Survey Database Design

【问题讨论】:

  • 您没有提供任何信息来说明答案在您的系统中的含义。它们是最终用户对问题给出的答案的历史存储吗?
  • 是的。 answers 表基本上是 user_id 和 s_question_options_id,它给了我们提出的问题和特定用户给出的答案。

标签: mysql survey


【解决方案1】:

这不是语法问题,这是数据库设计问题。

这里有两个主要数据集,questionsoptions,它们之间具有 多对多 关系,基于由 option_groups_id 定义的唯一集。大概,然后您将答案存储在某个地方,可能在此数据库中,但也可能完全以其他数据形式存储。我们假设您根据上面的查询使用question_option_id 存储答案。

为了保持历史答案的保真度,您需要通过某种方式将旧选项标记为“无效”。为此,您有两种选择:

  1. 通过创建新的question_answers_old 表或向question_answers 添加archivecurrent 标志,将“旧答案”存储添加到您的数据库中。

  2. 调整您存储在answer 记录中的数据,使其同时包含question_idoption_id 而不仅仅是question_option_id

如果可行的话,我的建议是#2。并将上面的表格替换为视图,除非性能要求您将其设为独立表格。

【讨论】:

    【解决方案2】:

    查看我的编辑以了解我的解决方案:

    INSERT INTO s_question_options (questions_id, option_choices_id)
    SELECT sq.id, so.id FROM s_questions sq JOIN s_option_choices so
    ON sq.option_groups_id = so.option_groups_id
    WHERE sq.id NOT IN (SELECT questions_id FROM s_question_options)
    OR so.id NOT IN (SELECT option_choices_id FROM s_question_options)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-12-24
      • 2010-11-26
      • 1970-01-01
      • 2019-08-21
      • 2013-01-27
      • 2012-03-25
      • 2012-02-12
      相关资源
      最近更新 更多