0

在我的调查问题 (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,以便当前问题可用但旧答案(存储在答案表中,并通过 引用s_question_options_id)仍然正确引用?

编辑

我可以在查找表中添加新问题或新 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 在表单中显示,但仍将数据保留在数据库中。

调查数据库设计

4

2 回答 2

0

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

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

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

  1. 通过创建新question_answers_oldarchivecurrentquestion_answers.

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

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

于 2013-05-23T01:49:23.407 回答
0

请参阅我的编辑以了解我的解决方案:

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)
于 2013-05-23T22:46:12.417 回答