Как лучше всего передавать и хранить, просмотры и лайки на PHP?

Хочется узнать у опытных разработчиков методы хранения и передачи данных например о просмотрах и лайках.
Есть PHP 7+Nginx+MySQL.
Самое очевидное для меня - это просто завести отдельную таблицу под просмотры например и лайки, где каждый просмотр пользователя и лайк фиксировался с привязкой к новости\посту и тд. , а потом на основе просмотренных постов например выдавались в ленте только те, которые не были еще просмотренными. Ну и каждый вывод поста бы запрашивал все лайки с ним связанные.
Способ мне кажется топорным и вообще не быстрым :)
А хочется сделать по уму, чтобы как то оптимизировать способ передачи и хранения, не нагружая сильно сервер и базу.

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

Возможно есть пути решения через NGINX или PHP, для этого?! Вообщем интересно кто и как реализует подобное в своих проектах или может знает пример реализации :)
  • Вопрос задан
  • 2499 просмотров
Пригласить эксперта
Ответы на вопрос 5
sergiks
@sergiks Куратор тега PHP
♬♬
Посты лайкаются и смотрятся неравномерно: бурлят свежие посты, статично висят старые-забытые.
Поэтому для кипящего ядра можно держать данные в оперативке, скажем, в Redis – туда писать, оттуда читать. Если ключа поста нет в Redis, то вынимать из БД. Периодически из Redis'а копировать в БД все данные и убирать из Redis данные по постам, которые перестали обновляться.

Часть нагрузки можно передать на клиент. При загрузке с сервера всем раздавать одинаковые данные о свежих постах (их id без содержания, если длинные). Далее по мере просмотра счётчики лайков/просмотров обновлять на клиенте, синхронизируя лайки с сервером не так часто. И скрипт на клиенте решает дальше, какие посты подгружать и показывать, учитывая локальные просмотры.

Ещё мысль: nginx умеет Lua. Можно операции с лайками/просмотрами поручить сольному nginx без PHP. Правда, возникает вопрос с авторизацией.
Ответ написан
А я бы кешировал просмотры и лайки и обновлял кеш при каждом новом лайке. Хранить такое количество данных лучше в click house. В памяти хранить кеш, поддерживать кеш в таблице, периодически обновляя. Как замена редису если вдруг тот очистится или рухнет. А подробности в кх. Иначе у вас база тормозить начнет через десяток миллионов записей. Редис не предназначен для хранения постоянных данных
Ответ написан
@IgorAlentyev
Добрый день! Попробую предложить решение, как бы я сделал.
Во первых, я бы не писал на чистом PHP, а использовал бы фреймворк, тот же Laravel, там есть функционал который вам нужен, и он поможет грамотно организовать всё и удобно работать с кешем. Но если хочется без фреймворков и у вас не планируется прям highload, то я бы делал как то так:
Для хранения лайков вам в принципе написали вариант, для новых постов храните в редисе/мемкеше, да где угодно, можно и прямо в базе, если у вас не будет огромной посещаемости, то и проблем не будет.

Что касается организации таблиц - как вариант, вот у вас есть пользователь, у него есть ID. Создаете таблицу, в неё user_id, liked_post_id. Это, если вам например нужно будет отдельно выводить лайкнутые посты конкретного юзера, ну и это поможет, если вам нужно отображать в ленте уже лайкнутые посты. (Главное не говнокодить, то есть не нужно на каждый пост в цикле делать отдельный запрос в БД. Получите сначала все лайкнутые посты пользователеля в массив, и при выводе в цикле постов, через array_search просто ищите нужный пост)

Если вам не нужно выводить лайкнутые конкретного пользователя, а нужно только выводить общее количество лайков поста, то самый простой вариант - у вас есть таблица с постами, добавляете туда likes_count, как то так. И на каждое нажатие лайка этого поста обновляете значение.

По поводу просмотров - логика примерно такая же, если вам нужно считать просмотры только с "детальной страницы поста", то при заходе на страницу поста увеличиваете значение views_count в БД у этого поста.
Если вам нужно отлавливать просмотры в списке, то есть JS библиотека, которая это умеет, скорее всего даже не одна, к сожалению я не помню как называется, но можно посерчить так - "js div в области видимости". Соответственно когда сработает событие JS библиотеки, делаете ajax на пхп файл, в который передаете ID поста, ну а дальше всё как выше написал.

Что касается производительности - не слушайте новичков, если у вас НЕ лютый highload, то всё у вас будет летать. MySql - очень быстрая БД, и несколько легких запросов не будут проблемой.

В ленте выводите не все посты сразу, используйте LIMIT offset, и выводите через постраничку или бесконечный скролл, что в принципе одно и то же, только в случае с бесконечным скроллом, вы ajax-ом подгружаете данные и вставляете в DOM.

Если у вас большое количество данных и будут тормоза, то есть куча статей с решениями таких проблем.
Одна из них - https://habr.com/ru/post/217521/

В любом случае, удачи и успеха!
Ответ написан
Комментировать
anton_reut
@anton_reut
Начинающий веб-разработчик
Главная проблема в том как твоя система будет определять просмотренные? Каждый раз перебор по сотням и тысячам записей в базе? Бред, БД упадет. Здесь надо сильно подумать. Ну или устроиться программером на Пикабу и подсмотреть как у них сделано ))
Ответ написан
sanchezzzhak
@sanchezzzhak
Ля ля ля...
Таблица для лайков, просмотров, голосования - это нормально нормально, вы не Гугл и не фейсбук
Голосование с оценкой
UIID, USER_ID, VOTE, POST_ID
Просмотры
UIID, USER_ID, POST_ID
Лайки
UIID, USER_ID, POST_ID

При голосование считаете 1 запросом количество, и обновление у новости, фото, видео итд. Счетчик.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы