Как лучше сделать подписку на ответы в иерархических комментариях?
Сразу определяем, что "лучше" - это оптимальное сочетание быстродействия, нагрузки и запросов к 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|%", что, мне кажется, замедлит работу скрипта, который всего лишь должен показать циферку одну с количеством непрочитанных комментариев. Как-то это слишком нагрузно, имхо, для одной циферки, имхо.
Сразу предупрежу, что о том, какая там нагрузка создается при использовании поиска по подстроке - я понятия не имею, не гуглила в эту сторону и не проверяла. Просто пришло в голову решение, но оно мне не нравится. Может быть, у вас есть решения этого вопроса более лаконичные и правильные или вы просто убедите меня в том, что этот вариант вполне рабочий и совсем не напряжный.
В общем, жду ответов, желательно - от тех, кто сталкивался с подобными вопросами.
Допустим пользователь подписался на вопрос, затем пришел через день и у него 10 ответов, можно ли считать что все 10 ответов прочитаны после того как он перешел на вкладку "новые ответы" или каждый ответ считается отдельно?
Если он перешел на вкладку Новые ответы, то ему только показывается, сколько новых ответов в каждом вопросе, на который он подписался, вопрос мой именно об этом.
Что же касается того, как комментарии становятся из непрочитанных прочитанными, то это когда он зайдет в обсуждение, создадутся записи о том, что эти комментарии, которые он на этой странице видит, прочитаны. А в дальнейшем я хочу сделать это асинхронно, когда человек проскролил до непрочитанного комментария, тот вспыхнул и стал прочитанным.
Но это к моему вопросу отношения не имеет, я спросила лишь о том, как лучше посчитать количество непрочитанных комментариев.
а) родителей указывать по порядку, то есть 1-12-123 и делать запрос LIKE '1-12-%' и повесить на это поле индекс.
б) делать запросы в цикле после добавления коммента для получения всех родителей, а потом пройтись по подпискам всех родителей и увеличить в них счетчик. При заходе пользователя счетчик обнулять.
в) ограничить вложенность 2-мя уровнями.