In my database of survey questions (s_questions) and possible answers (s_option_choices), I have a lookup table (s_question_options):
Create syntax:
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;
Populated thusly:
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;
If I update s_option_choices
with new/changed/deleted possible answers, what syntax will update my lookup table s_question_options
so that current questions are made available but old answers (stored in an answers table, and referenced via s_question_options_id
) are still correctly referenced?
Edit
I can add new questions or new option_choices to my lookup table with:
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)
It's the same select query as the one used originally to populate the lookup table, but with the condition that a) the question entered has not been entered before, or b) the option_choice has not been entered before.
Changing option_choices should not be a requirement, it makes no sense, and has no place in the game of referential integrity.
Deleting option_choices can be solved by my answers table foreign key (id) ON DELETE SET NULL. This will in effect set answers to questions with a deleted option_choice to NULL, and in my application, I can look for this and act accordingly (question not answered, or answered with now irrelevant data).
As was suggested, one could also set a display flag in the option_choices table (or even an array of option_choices in the app) that would prevent those option_choices from being displayed in the form yet still retain the data in the db.