Рассмотрим следующую установку;
users
+------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+-------------+------+-----+---------+----------------+
| user_id | smallint(5) | NO | PRI | NULL | auto_increment |
| username | varchar(10) | NO | | NULL | |
+------------+-------------+------+-----+---------+----------------+
... You'll have more columns, but you get the idea
-
questions
+----------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+----------------+
| qid | smallint(5) | NO | PRI | NULL | auto_increment |
| question | varchar(10) | NO | | NULL | |
| votes | smallint(5) | NO | | 0 | |
+----------+--------------+------+-----+---------+----------------+
-
votes
+--------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| qid | smallint(5) | NO | | NULL | |
| user_id| smallint(5) | NO | | NULL | |
+--------+-------------+------+-----+---------+-------+
В этой установке, я Идентификатор_пользователя 1 и голосование за вопрос ид 1
Когда пользователь голосов, их голосование помещается в пределах votes
INSERT INTO `votes` (`qid`,`user_id`) VALUES (1, 1);
Чтобы проверить, что они уже голосовали, просто выполните;
SELECT `user_id` FROM `votes` WHERE (`user_id`=1) AND (`qid`=1);
Если запрос возвращает все строки, мы знаем, что пользователь уже проголосовал, и мы не должны обрабатывать дублированный голос.
Конечно, это ограничивает нас только одним типом голосования - положительным или отрицательным - в зависимости от того, что вы решите отслеживать. Мы можем адаптировать votes
, чтобы сохранить тип голосования;
ALTER TABLE votes ADD type ENUM('up', 'down') NOT NULL DEFAULT 'up';
Который сделает нашу структуру таблицы следующей:
+---------+-------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------+-------------------+------+-----+---------+-------+
| qid | smallint(5) | NO | | NULL | |
| user_id | smallint(5) | NO | | NULL | |
| type | enum('up','down') | NO | | up | |
+---------+-------------------+------+-----+---------+-------+
И, опять же, адаптируйте запрос поиска;
SELECT `user_id` FROM `votes` WHERE (`user_id`=1) AND (`qid`=1) AND (`type`='up');
Рекомендуется использовать PRG (Post Redirect Get), чтобы (в основном) избежать этой проблемы. –
@Jack: PRG не полезен в моем случае, поскольку я обновляю счет в фоновом режиме и не могу перенаправить его на страницу. Я хочу реализовать систему подсчета очков, подобную переполнению стека. –
@InsaneCoder прочитал мой последний комментарий в моем ответе, если вам не нужно время, которое вы можете просто создать таблицу с идентификатором questionID и идентификатором учетной записи и получить результат с предложением WHERE, соответствующим как идентификатору accountID, так и currentQuestionID. Если возвращаемые строки> 0, вы не можете добавить счет снова, потому что пользователь уже оценил. – Steini