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

Сразу определяем, что "лучше" - это оптимальное сочетание быстродействия, нагрузки и запросов к mysql

У меня на сайте есть комментарии. Комментарии пишутся к разным объектам, к каждому комментарию могут быть ответы, то есть древовидная структура. При этом есть возможность подписаться на ответы: можно подписаться как на все обсуждение, например, новости, так и на ответы к конкретному комментарию (на всю ветку, на часть ветки и др.)

Структура таблицы комментариев проста: objectid, id, parent, text, user (в общем виде). В отдельной таблице у нас пользователи и есть таблица, в которой сохраняется запись, когда пользователь прочитал этот конкретный комментарий, в которой, если говорить коротко, 2 поля: userid и commentid

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

Когда речь идет о подписке на ветку все куда сложнее. К примеру, есть обсуждение:

Комментарий 1
+ Комментарий 2 - ответ к комментарию 1
+ + Комментарий 3 - ответ к комментарию 2
Комментарий 4
Комментарий 5
+ + Комментарий 6 - ответ к комментарию 5

Человек. к примеру, написал Комментарий 2 и ждет, когда ему ответят. При этом о том, что написаны комментарии 4, 5 и 6 он знать не хочет. В таблице подписок указано, на какой комментарий какого объекта (например, новости) он подписался, есть данные о том, что он уже видел комментарии 1 и 2 в таблице с записями. Но вот как отфильтровать лишние ветки, оставив только ответы на нужный комментарий? Все, что мне приходит в голову - добавить к комментарию поле, где указываются все родители, соответственно, если среди родителей есть комментарий 2 и этот комментарий не прочтен, то его нужно "посчитать". Но это поле со списком родителей окажется строкой (отдельно создавать сотни полей для родителей - бред), по которой нужно будет искать подстроку. То есть у комментария 3, например, будет в этом поле стоять "|2|1|" и нужно будет искать совпадение в этом поле по условию LIKE "%|1|%", что, мне кажется, замедлит работу скрипта, который всего лишь должен показать циферку одну с количеством непрочитанных комментариев. Как-то это слишком нагрузно, имхо, для одной циферки, имхо.

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

В общем, жду ответов, желательно - от тех, кто сталкивался с подобными вопросами.
  • Вопрос задан
  • 2781 просмотр
Пригласить эксперта
Ответы на вопрос 1
@http3
а) родителей указывать по порядку, то есть 1-12-123 и делать запрос LIKE '1-12-%' и повесить на это поле индекс.
б) делать запросы в цикле после добавления коммента для получения всех родителей, а потом пройтись по подпискам всех родителей и увеличить в них счетчик. При заходе пользователя счетчик обнулять.
в) ограничить вложенность 2-мя уровнями.
Ответ написан
Комментировать
Ваш ответ на вопрос

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

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