Как вы храните и отображаете, если пользователь проголосовал или нет на что-то? - PullRequest
8 голосов
/ 13 августа 2011

Я работаю над сайтом голосования, и мне интересно, как мне поступить с голосами.

Например, на SO, когда вы голосуете за вопрос (или ответ), ваш голос сохраняется, и каждый разЯ возвращаюсь на страницу и вижу, что уже проголосовал за этот вопрос, потому что кнопки вверх / вниз окрашены.

Как вы это делаете?Я имею в виду, у меня есть несколько идей, но мне интересно, не будет ли это тяжелой нагрузкой для базы данных.

Вот мои идеи:

  • Написатьпомощник, который будет проверять каждый вопрос о том, было ли проголосовано

    Это означает, что количество запросов будет зависеть от количества элементов, отображаемых на странице (обычно ~ 20)

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

    Выглядит нормально, потому что только один запросне имеет значения, сколько элементов на странице, но может нарушить дизайн MVC / модели домена, не знаю.

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

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

Как вы это делаете?Есть еще идеи?

Ответы [ 3 ]

1 голос
/ 15 августа 2011

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

Предположим, что вы сохраняете голоса в user_votes, когда голосование подано со структурой таблицы, подобной приведенной ниже.

id of type int autoincrement
user_id type int, Foreign key representing users table
question_id type of int, Foreign key representing questions table

Теперь, когда пользователь войдет в систему, когда вы выбираете вопросы, выполните левое соединение с идентификатором пользователя в таблице user_votes.

Что-то вроде

SELECT q.id, q.question, uv.id 
   FROM questions AS q 
   LEFT JOIN user_votes AS uv ON 
      uv.question_id = q.id AND 
      uv.user_id = <logged_in_user_id> 
   WHERE <Your criteria>

В представлении вы можете проверить наличие идентификатора. Если это так, проголосовали, в противном случае нет.

Возможно, вам придется изменить поля таблицы вопросов и все. Я предполагаю, что вы храните вопросы в таблице questions, а пользователи в таблице user. Все имеют первичный ключ id.

Спасибо

0 голосов
/ 04 мая 2012

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

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

0 голосов
/ 15 августа 2011

Вы можете использовать комбинацию предложенных вами стратегий.

Получить все голоса, поданные зарегистрированным пользователем, только за последние / активные вопросы и сохранить их в сеансе.

У вас есть те, которые с большей вероятностью понадобятся, при этом уменьшая количество, которое необходимо сохранить в сеансе.

В менее вероятном случае, когда вам нужны другие результаты, запростолько те, которые вам нужны и когда вам нужно.

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

...