Проектирование базы данных системы опроса - PullRequest
0 голосов
/ 25 февраля 2009

Я работаю над так называемой Системой наблюдения за поведенческими факторами риска (BRFSS), системой веб-запросов, которая работает с вопросниками, поступающими каждый год.

Мне было трудно придумать подходящий дизайн базы данных для него. Вот проблема: каждая анкета содержит около 80 вопросов, с демографической информацией, например, возраст, образование и т. д. и вопросы опроса, например, курение, здоровье и т. д. Каждый год некоторые вопросы меняются, некоторые нет. Источником данных является файл Excel с более чем 80 столбцами. Система должна поддерживать такие запросы, как:

SELECT [question var], [demo var], count(*) 
FROM survey 
WHERE age in (...) AND educ in (...) [etc] 
GROUP BY <question var>

Данные только для чтения, т.е. Никогда не меняйте один раз импортированный. Так что не нужно слишком много нормализовать. Интуитивно понятно, что таблица, похожая на электронную таблицу, хорошо сработает. скорость и пространство. Однако это становится проблемой, поскольку вопросы будут меняться, и тогда мы не сможем сохранить все данные в этой таблице, что необходимо из-за межгодовых запросов.

Я попытался нормализовать ответы в трех таблицах: вопросы, ответы и response_values, которые могут поддерживать варианты вопросов. Но тогда таблица ответов охватывает более 98 * 14268 = 1 398 264 строк за один год! Это действительно огромно. Запрос медленный, как сумасшедший!

Как мне разработать базу данных? Любая помощь приветствуется! Заранее спасибо!

пс. Я использую Python + Django + Sqlite.

Ответы [ 4 ]

6 голосов
/ 25 февраля 2009

Вы проверили DatabaseAnswers , чтобы увидеть, есть ли схема, которую вы могли бы использовать в качестве отправной точки?

1 голос
/ 25 февраля 2009

вам нужно как минимум 3 таблицы:

1) Questions, который содержит текст для каждого вопроса с ключом идентификатора автоинкремента

Например: (123, "Какого цвета ваши волосы?")

2) Questionaires, что отображает Q # на вопросы.

например) вопрос № 10 на вопроснике № 3 соответствует вопросу № 123.

3) Answers, которые связывают каждого респондента со своим вопросником и данными

Например, ответ Боба на вопрос № 10 в вопроснике № 3 - «коричневый».

Вы должны увидеть, как легко добавлять новые вопросники, используя существующие вопросы и добавляя новые вопросы. Да, будут огромные таблицы, но хороший движок базы данных должен легко обрабатывать 1М записей. Вы можете использовать разбиение, чтобы сделать его более эффективным, например разделение по годам.

Я оставлю это в качестве упражнения о том, как преобразовать это в SQL.

1 голос
/ 25 февраля 2009

Звучит как случай для звездной схемы.

У вас будет (огромная) таблица фактов, подобная этой:

question_id, survey_id, age_group_id, health_classifier_id, is_smoking ..., answer_value

и денормализованные таблицы размеров:

age_group: имя_группы, min_age, max_age, age_group_id

1,4 миллиона строк не очень похоже на такую ​​систему.

Некоторые базы данных имеют специальные функции для поддержки запросов к схеме такого типа:

На Oracle это будет:

  • «размеры» для поддержки агрегации по всем размерам
  • индекс растрового изображения для фильтрации по таким атрибутам низкой мощности, как age_group_id и is_smoking
  • индекс соединения растрового изображения для фильтрации по атрибутам с низким количеством элементов в объединенной таблице, т.е. выбор из таблицы фактов, но фильтрация по min_age в таблице age_group.
  • таблицы разбиения для обработки больших таблиц
  • материализованные представления для результатов предварительного расчета агрегации

Существуют также специализированные системы БД для такого типа данных, называемые многомерными базами данных.

проверьте, есть ли аналогичные конструкции для вашей базы данных, или рассмотрите возможность переключения ядра базы данных

0 голосов
/ 25 февраля 2009

Я тоже думал о моем посте на stackoverflow. Вот как я могу использовать денормализованную широкую таблицу (более 80 столбцов) для поддержки изменения вопроса каждый год, а также для агрегирования перекрестных таблиц. Пожалуйста, прокомментируйте. Спасибо

  1. Создайте новую таблицу для каждого года с вопросами, размещенными в столбцах например

    ID год возраст секс образование доход ... курить ВИЧ пить ...

  2. Создайте две таблицы: Question и Query_Year, таблицу «многие ко многим» Question_Year. Затем мы можем заполнить список вопросов, доступных на определенный год, и наоборот.

  3. Запросы в течение одного года легко. И запросы между годами, мы можем использовать оператор UNION. Поскольку вопросы должны быть совместимы между выбранными годами, UNION является законным. например,

    ВЫБРАТЬ * ИЗ ( ВЫБЕРИТЕ id,,, COUNT () ОТ опроса_2001 СОЮЗ ВСЕХ ВЫБЕРИТЕ id,,, COUNT () ОТ опроса_2003 СОЮЗ ВСЕХ ВЫБЕРИТЕ id,,, COUNT (*) ОТ обследования_2004 СОЮЗ ВСЕХ и т. д. ) ГДЕ ( ВОЗРАСТ в (...) И EDUC в (...) И и т. д. ) GROUP BY,

Полагаю, UNION - это оператор отношений, который не должен снижать эффективность СУБД. Так что не повредит, если я объединю много таблиц по объединению. Движок также может выполнить некоторый анализ запросов, чтобы повысить скорость.

Я думаю, что это достаточно и достаточно просто. Пожалуйста, прокомментируйте. Спасибо!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...