MySQL « Структура БД для механизма опроса
Сейчас делаю модуль опроса... Чето запарился со структурой... Вы бы как организовали(цели: удобство в работе; скорость)?
Как организовано у меня сейчас(хочу либо сделать заново, либо улучшить):
1. Таблица pref_polls:
2. pref_poll_voters:
Как организовано у меня сейчас(хочу либо сделать заново, либо улучшить):
1. Таблица pref_polls:
- id
- quest
- answers(варианты ответа разделенные через "|")
- security(метод учета голосов(по ip, кукам и т.д.))
- start_time
- end_time
- stopped
2. pref_poll_voters:
- ip
- dtime
- poll_id
- 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;