Прочитано/Не прочитано

Горбушка

Ищу её...
Регистрация
2 Май 2008
Сообщения
3.444
Реакции
2.524
Всем привет!

Есть задачка - реализовать в системе, схожей с форумной, функционал подсветки записей, которые пользователь не просматривал. Отсюда вытекает вопрос - как?

Первое что приходит в голову - в каждой записи хранить ID пользователей, которые её просмотрели. Возникает сложности с проверкой для категорий, т.к. вложенность не ограниченная... Да и в базе хранить кучу мусора не хочется.

Дальше вариант с хранением информации в куках. Но если пользователь их удалит - все записи будут не просмотренными по умолчанию.

В добавок к этим 2 вариантам - а как сделать "Отметить всё прочитанным"? Это ж задница писать в каждую запись ID пользователя.

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

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

Четвёртый вариант представляет из себя обратный фикс - мы не только помечаем непрочитанные с предыдущего визита, но и пишем ID в базу. При просмотре из БД они удаляются. При этом записи чистятся по крону, к примеру. А делаются только для активных пользователей. При следующем визите запрашиваем новые + подсвечиваем те, что уже есть в БД. Ну и чистим те, что по времени устарели (хранить что пользователь не читал год назад не самая удачная затея для БД).

Ок, 4-ый вариант кажется не плохим, но есть совершенно другой вариант, основанный на счётчиках. Да и опять же, хранить мусор в виде списка всех ID статей не очень хочется. Человек зарегислся чтобы посмотреть 1 статью, а это пораждает 100500 записей в БД на неопределённый срок. Зато мусора не будет для активных пользователей. Если пользователь прочитал всё - в БД записей не останется. Так же и с теми, кто не посещает систему - информация по ним будет вычищаться по кнону...

Вариант 5 - мы храним в БД для каждого пользователя количество постов на момент последнего прочтения для каждой категории/записи. Т.е. в категории 20 записей, пользователь прочитал 19 - значит есть непрочитанные. В записи есть 20 вложений, пользователь прочитал 19 - значит запись не прочитана. Вариант снижает нагрузку в том случае, если человек уже прочитал все записи. В этом случае сравнивается только общее количество во всей системе и нет нужды проходить по каждой категории. Так же вариант "Отметить всё прочитанным" для категории выглядит лишь как приравнивание количества постов. Недостаток тот же - куча мусора в БД.
А теперь, если Вас хватило на прочитать это всё или Вы тупо не открыли спойлер, а как правильно хранить эту информацию? Как это хранит, к примеру, XenForo? phpBB? vBulletin?
 
Мне тоже интересна эта тема. Хочу начать мутить свой форум через пару месяцев.

Представляется такой вариант:
1. Хранить историю последнего захода на сайт. Всё, что создано позже — помечать как непрочитанное. Это вообще никак нигде хранить не надо.
2. Хранить последнее посещение раздела. Выводить на главной жирным раздел, если в нем есть темы, созданные позже.
3. Темы... Но тут могут быть темы, которые созданы раньше, чем он посещал, но тем не менее не прочитаны. Как тут быть? А вот дальше пока мысль не идет. Надеюсь, кто-нибудь разовьёт эту мысль. Что-то, хранимое у пользователя? Из технологий представляются куки и rss.
ЗЫ. Вот написал и вижу, что пп. 1 и 2 невозможны. Мде...
 
Последнее редактирование:
С месяц назад думал над реализацией похожего.

1) на пользователе или в сессии имеет смысл хранить от силы историю (10-50) переходов по разделам сайта. Хранить все просмотренные id не имеет смысла по 2м причинам:
- куки всё равно гоняются по http, а значит лишняя нагрузка на твой сервер;
- выборка из базы типа IN (...) очень медленная на большом количестве row.

2) храним последний заход пользователя - примерно так сделано на searchengines:
+ легко реализуется
- скучно и неинформативно

3) отдельная таблица со связкой id записи, id пользователя, время просмотра (типа хабр: всё комментарии, что после этого времени считаем не просмотренными) или страница просмотра (типа xenforo).
+ при хорошей оптимизации SQL join на эту таблицу будет занимать миллисекунды
+ для редких посетителей все нормально
+ достаточно подробная инфа для удобства пользования этой фичей.
- плохо с такими маньяками как я, которые пролистали десятки тысяч тем, а значит таблица будет раздуваться. Но возможно это не так и критично, просто посидеть пару часов/дней над нормальным join/индексами и летать всё будет даже при 10кк rows
3a) теоретически можно схлопываться диапазоны просмотренных, но тут надо гуглить оптимальные алгоритмы, а то замедлишь вместо ускорения. Или использовать буквально два схлопывания: с начала и с конца тогда это всего лишь 2 условия, которые отработают по индексам.
 
Имел опыт с Xenforo. Там вариант отдельной таблицы для отслеживаемых пользователями тем:

Column Type
user_id int(10) unsigned
thread_id int(10) unsigned
email_subscribe tinyint(3) unsigned [0]

Как по мне самый логичный вариант, я бы тоже так делал. Не думаю, что прям сильно раздуется таблица.
 
Nei, вообще не в тему...
 
Мне кажется, надо делать таблицу визитов.
PHP:
CREATE TABLE `visits` (
  `id` int(11) NOT NULL auto_increment,
  `ip_adr` varchar(15) NOT NULL default '',
  `referer` varchar(250) NOT NULL default '',
  `country` char(2) NOT NULL default '',
  `client` varchar(100) NOT NULL default '',
  `visit_date` date default NULL,
  `time` time NOT NULL default '00:00:00',
  `on_page` varchar(255) NOT NULL default '',
  PRIMARY KEY  (`id`)
) TYPE=MyISAM;
И при заходе пользователя (client) в категорию сравнивать, был ли он в темах этой категории (по адресу on_page).
Заодно и статистика соберётся. Минус — нагрузка. Но возможно не такая большая, ведь пи просмотре категории мы уже знаем выбранные темы и выборка будет в 10-20 объектов. Кстати, видел механизм, когда с целью снижения нагрузки со временем таблица переименовывалась, чтобы не разрастаться. Например, «visits_2016_07» — визиты за июль 2016. Для статистики самое то, и проще выборки делать, однако для маркировки просмотренных тем возможно не подойдёт, надо думать.

Если не надо так жёстко, есть неточный, но более простой путь,основанный на псевдоклассе :visited
1. Все не просмотренные ссылки на темы — применить жирный шрифт.
2. Псевдоклассу :visited присвоить нормальный шрифт.
3. Хранить дату захода пользователя в категорию. Если есть более новые ответы в темах категории — выделить категорию жирным.
+ Почти не создаёт нагрузку.
- Не собирает статистику.
- При смене браузера статистика заходов обнулится.
- Отметить всё прочитанным — сложно. Наверное, решаемо с помощью js. Отметить категории прочитанными — не проблема. А вот со статьями хз.

От себя.
Честно говоря, я склоняюсь больше к тому, чтобы не собирать статистику с помощью PHP. На хостинге, как правило, и так есть серверные скрипты.
 
Последнее редактирование:
Назад
Сверху