MySQL « Структура БД для механизма опроса

Сейчас делаю модуль опроса... Чето запарился со структурой... Вы бы как организовали(цели: удобство в работе; скорость)?

Как организовано у меня сейчас(хочу либо сделать заново, либо улучшить):

1. Таблица pref_polls:
  1. id
  2. quest
  3. answers(варианты ответа разделенные через "|")
  4. security(метод учета голосов(по ip, кукам и т.д.))
  5. start_time
  6. end_time
  7. stopped


2. pref_poll_voters:
  1. ip
  2. dtime
  3. poll_id
  4. answer

1 ответов


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

pref_polls:


id INT
quest - VARCHAR 255
answers(варианты ответа разделенные через "|") - вот тут, я бы предложил вам использовать тип SET
security(метод учета голосов(по ip, кукам и т.д.)) - а тут ENUM
start_time - DATETIME
end_time - DATETIME
stopped - TYNEINT или ENUM ('Да', 'Нет')
 

pref_poll_voters:

id - INT
ip - VARCHAR
dtime - DATETIME
poll_id - INT
answer - ENUM
 

То есть.

1. В таблицу pref_poll_voters вы добавляете ID. Должно быть поле с уникальным значением. Иначе удалять записи будет очень проблемно. Также не забудьте сделать по нему индекс.

2. SET от ENUM отличается тем, что первый множество из множества, а второй, один из множества. В случае если вы сделаете answers как SET, например так ('Да','Нет','Не знаю', 'Не понимаю'), то в значение поля answer, таблицы pref_poll_voters, вы тоже самое внесете ('Да','Нет','Не знаю', 'Не понимаю'), только в первом случае все варианты будут активны, а во тором случае, вы укажите только тот вариант, который выбрал пользователь. По умолчанию, поля типа SET и ENUM это индексированные списки, поиск по ним работает быстро. Быстрей чем по строкам.

PS: Если не понятно, скажите. Попробуй более детально мысль донести.


--
-- Определение таблицы Опросов
--
DROP TABLE IF EXISTS `polls`;
CREATE TABLE IF NOT EXISTS `polls` (
  `id`      int(11) UNSIGNED NOT NULL AUTO_INCREMENT  COMMENT 'Идентификатор опроса',
  `name`    varchar(64) NOT NULL                      COMMENT 'Название опроса',
  `amount`  int(11) UNSIGNED NULL                     COMMENT 'Сумма вознаграждения',
  `created` int(10) UNSIGNED NOT NULL                 COMMENT 'Дата создания',
  `status`  tinyint(1) UNSIGNED NOT NULL DEFAULT 1    COMMENT 'Состояние опроса (0|1)',
  `descr`   varchar(255) NOT NULL                     COMMENT 'Описание опроса',
  PRIMARY KEY (`id`),
  KEY `name_idx` (`name`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;

--
-- Определение таблицы Вопросов
--
DROP TABLE IF EXISTS `questions`;
CREATE TABLE IF NOT EXISTS `questions` (
  `id`          int(11) UNSIGNED NOT NULL AUTO_INCREMENT  COMMENT 'Идентификатор вопроса',
  `poll_id`     int(11) UNSIGNED DEFAULT NULL             COMMENT 'Идентификатор родительского опроса',
  `question`    varchar(255) NOT NULL                     COMMENT 'Содержание вопроса',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;

--
-- Связывание таблицы `questions` с таблицей `polls`  по внешнему ключу
-- При удалении записи из таблицы `polls` удаляется всё связанное
-- содержимое из таблицы `questions`
--
ALTER TABLE `questions`
  ADD CONSTRAINT `poll_question_ibfk_1`
  FOREIGN KEY (`poll_id`) REFERENCES `polls`(`id`)
    ON DELETE CASCADE
    ON UPDATE CASCADE;

--
-- Определение таблицы `answers`
--
DROP TABLE IF EXISTS `answers`;
CREATE TABLE IF NOT EXISTS `answers` (
  `id`          int(11) UNSIGNED NOT NULL AUTO_INCREMENT  COMMENT 'Идентификатор ответа',
  `question_id` int(11) UNSIGNED DEFAULT NULL             COMMENT 'Идентификатор родительского вопроса',
  `answer`      varchar(255) NOT NULL                     COMMENT 'Содержание ответа',
  PRIMARY KEY   (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;

--
-- Связывание таблицы `answers` с таблицей `questions`  по внешнему ключу
-- При удалении записи из таблицы `questions` удаляются соответствующие этой
-- записи данные из таблицы `answers`
--
ALTER TABLE `answers`
  ADD CONSTRAINT `question_answer_ibfk_1`
  FOREIGN KEY (`question_id`) REFERENCES `questions`(`id`)
    ON DELETE CASCADE
    ON UPDATE CASCADE;

--
-- Определение таблицы `polls_users`
--
DROP TABLE IF EXISTS `polls_users`;
CREATE TABLE IF NOT EXISTS `polls_users` (
  `user_id`     bigint(20) UNSIGNED DEFAULT NULL  COMMENT 'Идентификатор пользователя',
  `poll_id`     int(11) UNSIGNED DEFAULT NULL     COMMENT 'Идентификатор опроса',
  `staus`       tinyint(1) UNSIGNED DEFAULT 0     COMMENT 'Статус опроса (пройден -1, не пройден -0)',
  `invite`      tinyint(1) UNSIGNED DEFAULT 0     COMMENT 'Пользователь приглашён в этот опрос -1, пользователь сам прошёл этот опрос (или не приглашён) - 0)',
  PRIMARY KEY   (`user_id`, `poll_id`),
  KEY `poll_idx` (poll_id)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;


--
-- Связывание таблицы `polls_users` с таблицей `users`  по внешнему ключу
-- При удалении записи из таблицы `users` удаляются соответствующие этой
-- записи данные из таблицы `polls_users`
--
ALTER TABLE `polls_users`
  ADD CONSTRAINT `polls_users_ibfk_1`
  FOREIGN KEY (`user_id`) REFERENCES `users`(`id`)
    ON DELETE CASCADE
    ON UPDATE CASCADE;

--
-- Связывание таблицы `polls_users` с таблицей `polls`  по внешнему ключу
-- При удалении записи из таблицы `polls` удаляются соответствующие этой
-- записи данные из таблицы `polls_users`
--
ALTER TABLE `polls_users`
  ADD CONSTRAINT `polls_users_ibfk_2`
  FOREIGN KEY (`poll_id`) REFERENCES `polls`(`id`)
    ON DELETE CASCADE
    ON UPDATE CASCADE;

--
-- Определение таблицы `answers_users`
--
DROP TABLE IF EXISTS `answers_users`;
CREATE TABLE IF NOT EXISTS `answers_users` (
  `user_id`   bigint(20) UNSIGNED DEFAULT NULL  COMMENT 'Идентификатор пользователя',
  `answer_id` int(11) UNSIGNED DEFAULT NULL     COMMENT 'Идентификатор ответа',
  `poll_id`   int(11) UNSIGNED DEFAULT NULL     COMMENT 'Идентификатор опроса',
  `answered`  int(10) UNSIGNED NOT NULL         COMMENT 'Дата ответа',
  PRIMARY KEY   (`user_id`, `poll_id`),
  KEY `poll_idx` (poll_id)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;

--
-- Связывание таблицы `answers_users` с таблицей `answers`  по внешнему ключу
-- При удалении записи из таблицы `answers` удаляются соответствующие этой
-- записи данные из таблицы `answers_users`
--
ALTER TABLE `answers_users`
  ADD CONSTRAINT `answer_users_ibfk_1`
  FOREIGN KEY (`answer_id`) REFERENCES `answers`(`id`)
    ON DELETE CASCADE
    ON UPDATE CASCADE;

--
-- Связывание таблицы `answers_users` с таблицей `users`  по внешнему ключу
-- При удалении записи из таблицы `users` удаляются соответствующие этой
-- записи данные из таблицы `answers_users`
--
ALTER TABLE `answers_users`
  ADD CONSTRAINT `answer_users_ibfk_2`
  FOREIGN KEY (`user_id`) REFERENCES `users`(`id`)
    ON DELETE CASCADE
    ON UPDATE CASCADE;

--
-- Связывание таблицы `answers_users` с таблицей `polls`  по внешнему ключу
-- При удалении записи из таблицы `polls` удаляются соответствующие этой
-- записи данные из таблицы `answers_users`
--
ALTER TABLE `answers_users`
  ADD CONSTRAINT `answer_users_ibfk_3`
  FOREIGN KEY (`poll_id`) REFERENCES `polls`(`id`)
    ON DELETE CASCADE
    ON UPDATE CASCADE;