Страницы

Поиск по вопросам

вторник, 27 ноября 2018 г.

Правильное хранение лайков/дислайков (голосования) в БД

Есть сайт, на котором должна быть организована система голосования (лайк/дислайк). Если записывать в БД информацию в виде номер_записи - id_пользователя, то вроде бы всё хорошо. Но. Возьмем 100 записей и 100 пользователей. Каждый из них проголосует за каждую запись, в итоге в БД будет содержаться 10.000 записей, а это проблема. Почитав немного, изменил таблицу и она стала вида: номер_записи - id_всех_пользователей_которые_голосовали При тех же условиях вместо 10.000 получим всего 100 записей в БД.
Добавление нового id пользователя происходит так:
забираем всю строку из БД, где номер записи равен N SELECT FROM WHERE users_id LIKE '%id_пользователя%' - запрос, чтобы проверить существование уже этого id в строке в случае успешной проверки добавляем в конец строки новый id и заносим в БД новую строку.
Насколько это правильный подход к хранению такого рода информации? Какие есть альтернативы? Готов услышать и принять к сведению.


Ответ

Прикинем, как часто что требуется.
сумма (или две суммы: за и против) по конкретному голосованию – супер-часто – при каждом открытии страницы с этим голосованием. голосовал ли данный юзер за данный опрос? – реже, при приёме нового голоса. кто проголосовал за / против за данный вопрос? – ещё реже, если вообще это открытая инфа. как и где голосовал данный юзер – тоже, вероятно, совсем редко, если вообще.
Итого, текущие суммы храним в каком-нибудь быстром кэше, типа memcached/apc/redis.
При поступлении нового голоса в БД надо проверить, голосовал ли? и сохранить голос + обновить кэшированную сумму. Хорошо иметь отдельную таблицу только для голосов:
id_опроса id_юзера голос_плюс_минус (1 бит)
Основной индекс составной - по обоим id - т.к. будем искать и по вопросу-юзеру (можно ли принять голос - может быть только одна запись с парой qid,uid) и по опросу (кто-как). И ещё индекс только по юзеру (где голосовал).
Да, будет запись в БД и двух индексах на каждый отданный голос. Хоть 10 млн. – это нормально. Каждая запись – два 32-битных целых и 1 бит. Когда проект вырастет – станете горизонтально масштабировать – скажем, id опросов меньше X уедут на доп. MySQL сервер.

Комментариев нет:

Отправить комментарий