Я намеренно формулирую это как общий вопрос, хотя я использую ORM Джанго для реализации этих таблиц. Вот мои модели Django , если вы хотите взглянуть.
Загадка
У меня есть несколько таблиц со следующими отношениями:
Survey <--m2o-- Page <--m2o-- Category <--m2o-- Question <--m2o-- Choice <--?-- Response
| | | | |
|- name |-number |- name |- sortid |- sortid
|- sortid |- text |- text
|- text |- short
|- qtype
Где m2o
- это сокращение от «многие к одному», у каждой таблицы есть неявный первичный ключ, и мой вопрос касается того, как организовать таблицу ответов.
Таблица ответов должна иметь какое-то отношение к таблице пользователя (в зависимости от определения таблицы это может быть один к одному или много к одному). Цель таблицы - хранить ответы пользователей на конкретные вопросы. Проблема, с которой я столкнулся, заключается в том, что в зависимости от типа вопроса мне нужно хранить ответ в столбце другого типа в таблице ответов. Например, таблица может напоминать:
| user | (question) | (qtype) | choice | response |
|------+------------+-----------------+-----------+-------------------------------|
| 1 | Q1 | Select One | A | False |
| 1 | '' | '' | B | False |
| 1 | '' | '' | C | True |
| 1 | .. | '' | D | False |
| 1 | Q2 | Select Multiple | 1 | True |
| '' | '' | '' | 2 | True |
| '' | '' | '' | 3 | False |
| '' | '' | '' | 4 | True |
| '' | Q3 | Long Text | NULL | "It was the best of times..." |
| '' | Q4 | Select Explain | A | False |
| '' | '' | '' | B | False |
| '' | '' | '' | C | False |
| '' | '' | '' | D (other) | True |
| '' | '' | '' | Explain | "I actually prefer bananas." |
Я добавил столбцы для ясности, которые бы неявно определялись отношениями и поэтому не присутствовали в реальной таблице. Они обозначены ( )
. Кроме того, choice
будет фактически внешним ключом.
Может показаться, что столбец ответа может быть текстовым столбцом. Если разбить его на две или более колонки, такие как response-text
и response-boolean
, это выглядит грязно. Мы могли бы легко иметь сотни строк для одного пользователя.
Я также думал об организации таблицы следующим образом:
| user | survey | response (key-value store) |
|------+--------+--------------------------------------------|
| 1 | 1 | {"q1": "C", "q2": "1,2,4" |
| | | "q3": "It was the best of times..." |
| | | "q4": "Other: I actually prefer bananas."} |
| 2 | 1 | {...} |
| 3 | 1 | {...} |
Как бы вы определили эту таблицу и почему?
Бонусные баллы, если вы объясните, в каком контексте ваше определение не сработает.
Если вы хотите представить мою ситуацию, вот несколько заметок о моем контексте:
- Таблица ответов может обновляться несколько раз во время опроса, но никогда после этого. Эта конкретная таблица OLAP, или в основном для чтения. Единственные запросы, которые я буду выполнять, - экспортировать таблицу для статистического анализа в коммерческий программный пакет.
- Ответы разных пользователей редко бывают идентичными (с высокого уровня)
- Производительность не является проблемой в том смысле, что только 15 пользователей будут одновременно подключены к приложению во время сеанса администрирования опроса. Только один пользователь (я) будет просматривать данные после их сохранения.
Я подозреваю, что моя ситуация близка к примеру N1NF в Википедии .
Должна ли эта таблица быть полиморфной?
Я только что слышал о наследовании нескольких таблиц или полиморфизме, и я не уверен, как применить его к этой проблеме. В частности, я не уверен, какие таблицы выиграют от наследования. Например, должен ли Response расширить выбор? Должна ли страница расширять опрос?