armadillo, не, это слишком жестокий фильтр кто такой дайджест? вообще, не мог бы ты более развёрнуто говорить, а то моя твоя не понимать
птичка "добавить этот форум в дайджест". И тогда по нему строится история посещений и поднятые темы показываются в списке последних. Остальные разделы тихо сидят и не отсвечивают. Захотел - и отписал раздел "флейм" из дайджеста.
Фишка в том, что в форуме есть не только темы, по которым у меня есть связки в forums_last_readed о прочитанных темах, но и есть просто новые темы, в которые я никогда не входил. Вопрос вот именно в том, как имея одну запись ID форума; ID юзера; сделать так, что бы ему 100% достоверно показывало, что там либо что-то есть, либо нету. Держать запись типа: USER ID; FORUM ID; 1/0; Не проблема, вопрос в том, КАК определить что в форуме я прочитал все темы и новых сообщений там НЕТ. Если тыкать в кнопку "Отметить форум как прочитанный" - оке, no problemo. А если там было: 3 темы за которыми я слежу с новыми сообщениями и 5 новых тем. Просмотрю я все 8. Как мне определить при просмотре 8-й темы, что новые сообщения кончились? При входе в форум выбирать что-ли ID'ки всех непросмотренных тем и вогнать их в сессию и по мере просмотра тем удалять из массива просмотренные темы и как только их кол-во будер равно 0, апдейтим запись USER ID; USER FORUM; 0; ? Единственное, если форум большой и много обновлений, в вессии будет таскаться довольно большой массив. З.Ы. Между прочим неплохая идея, надо будет попробовать
добавление поста [sql]insert into юзеры*темы select ".$topic_id.", ".$post_id.", user_id from users left join юзеры*темы ut on ut.topic_id=".$topic_id." and ut.user_id=users.user_id where ut.user_id is null[/sql] новой темы - еще проще. просмотр темы [sql]delete from users_topic where user_id=".$user_id." and topic_id=."$topic_id[/sql] [sql]select count(ut.topic_id) as viewedforum from users_topic ut, topics t where ut.user_id=."$iser_id." ant ut.topic_id=t.topic_id and t.forums_id=.$fid[/sql]
хм.. почитал, подумал. А как такой вариант. Есть две дополнительные таблички, в одной хранится маркер для категории в целом (id юзера/id форума/upper_date/lower_date)(у меня форум разделен на категории просто, без вложений), в другой маркер для темы (id темы/id форума/id юзера). А upper_date и lower_date являются ограничивающими датами в выборке. Примерно так: Код (Text): все темы, что выше этой даты - все непрочитанные //upper_date если в этом интервале и есть маркер на тему - прочитана, иначе - непрочитанная //lower_date все темы, что ниже этой даты - всегда прочитаны если мы щелкаем на тему выше верхней даты - верхней дате присваиваем значение даты темы, плюс создаем маркер для этой темы(прочитана). если щелкаем на тему в интервале - создаем маркер. если заходит новый юзер - нужно все темы пометить как прочитанные (я так думаю ) - просто в маркер для форума для граничных дат выставить текущее время. lower_date автоматически можно присваивать от темы, выше всего лежащей от нее без непрочитанных Т.е. Код (Text): прочитано 1 непрочитано 2 прочитано 3 прочитано 4 //lower_date lower_date можно присвоить дату из номера 3. все маркеры темы ниже lower_date легко удаляются одним запросом. если в интервале от граничных дат все маркеры (прочитаны) - для обоих дат присваиваем значение верхней граничной даты и удаляем маркеры. вот теперь все это реализовать надо. "Деревянным" методом вроде получается, это когда тупо куча запросов, вложенные циклы (это все от малознания ).
antonn, так в том и проблема, собственно )) Либо - избыток хранимых данных в угоду сложности, либо — большое количество запросов, либо сложный парсинг строк регулярками... и везде условия, типа — 2 недели устаревания, и т.п.
Горбунов Олег ну пока получается на каждую страницу списка тем форума 3 запроса и при просмотре темы 2 минимум (плюс на каждый маркер, если его создавать - по запросу). Решил, что лучше я сделаю маркеры темы отдельным записями, а не серилизованным массивом в записи для целого форума в текстовом виде... дурацкий вопрос 32 запроса на то, чтобы нарисовать страницу сайта - это нормально?
кроме числа запросов, есть еще число строк, которые прийдется просмотреть - а это тоже процессорное время зависит от сложности и структуры. но, имхо, многовато....
практика показывает, что "нинада эта!" новые темы будут достоверно показываться. а старые непросмотренные - не актуальны, так как за всё это время пользователь так и не удосужился её просматреть. а ты хочешь и на ёлку влезть и не поцарапаться? =)
вариант 1 старые непросмотренные пишем в базу. просмотренные удаляем. недосмотренные пишем. Недостаток: большой объем на непросмотренные темы. Вариант 2 пишем просмотренные (с флагом) и недосмотренные. Недостаток: большой объем на все просмотренные темы. Не уверен, что будет намного больше чем просто список недосмотренных - большинство юзеров не так активны. Вариант 3. пишем недосмотренные, просмотренные удаляем. несмотренные вообще храним в бинарном поле - допустим 16-32к на юзера, 128-256к ид тем. на 50к юзеров объем 32к*50к=1.5гб. упс. ))
armadillo все оптимизируется вводом двух ограничивающих дат, см. Пт Июн 22, 2007 10:45. нижняя дата устанавливаем минимум, от которого будут создаваться маркеры просмотренных тем (я решил хранить именно просмотренные), и эта дата постоянно увеличивается (при условии активного пользователя), даже не надо устраивать пассивное ограничение в 2 недели (хотя можно на всякий случай месяц там поставить). Все темы ниже этой даты считаются прочтенными всегда (и ведь да, если в какой то старой теме будет изменение - значение даты у нее изменится на большую, чем ограничение). Верхняя дата устанавливает границу сверху, выше которой темы считаются свежими всегда - если пользователь отсутствовал долго и зашел, то не нужно создавать кучу маркеров - они все равно помечены как не прочитанные. Ну а на те, что входят в интервал, создавать маркер в случае просмотра темы (плюс в маркер я пихаю дату последнего изменения темы - по этой дате можно определить последний просмотренный пост, ведь следующие новые посты будут с большей датой), а так же обновлять дату изменения в маркере, если он существует. Только нужно учесть несколько заковырок. При просмотре темы: Если выбирается тема выше up_date (верхняя дата), то нужно создать для нее маркер (либо обновить существующий - тема может быть старой, но обновленной). Для up_date установить значение даты изменения этой темы (поднимаем границу верхней даты выше - теперь, все новые темы, что попали в обновленный интервал дат - они автоматически свежие, ведь для них нет маркера в интервале!). Если выбирается тема в интервале ограничивающих дат, нужно также либо создать маркер для нее (либо обновить существующий). С маркером в интервале тема считается прочитанной. При просмотре форума: обновить нижнюю границу дат. Все темы, что окажутся ниже нее - прочитаны, и маркеры для них не нужны - удаляются маркеры. Если окажется, что в интервале граничных дат все темы прочитаны, то для обоих дат присваиваем значение up_date (верхней даты), получится, что подвинулась нижняя граница - удаляем все маркеры просмотренных тем, что лежат ниже - они ведт все равно прочитанными считаются. если маркеров для форума нет, а значение даты последнего изменения форума равно дате в маркере форума - для обоих дат присвиваем значение time() - просто постоянно повышаем нижнюю границу интервала, меньше придется в будущем обрабатывать. Теперь я просто создаю массив непрочитанных тем(именно не прочитанных, на его основе уже рисуется сам форум на хтмл) по такому принципу (делаю выборку по всем маркерам для форума+юзера): если маркер лежит в интервале граничных дат и дата его последнего изменения не совпадает с датой изменения темы - в массив (ведь это значит, что тема была изменена) если маркера нет - в массив (тема значит свежая, раз маркера нет) если дата изменения темы выше, чем верхняя граничная дата - в массив (все что выше верхней даты - автосвежее) итого, имеем массивчик, в котором лежат непрочитанные темы, в кач. ключей делаю id темы. при рисовании форума, просто делаю array_key_exists() для нужной темы - есть ключ - тема помечается как непрочитанная.
Нет смысла пытаться установить точный факт отсутствия непрочитанных тем в целом форуме. В большом форуме всегда будут непрочитанные темы, и как следствие он всегда будет подсвечен как не прочитанный. Даже в небольшом форуме я читаю далеко не все темы, как результат - в форуме нет ничего для меня интересного, а он подсвечен как непрочитанный. Я пришёл к выводу, что достаточно проверять факт прочитанности самой "свежей" темы форума, и на основании него подсвечивать форум или нет.
опять же, не спасает от актуальных, но неинтересных тем. лично я пришёл к выводу, что подсвечивать форум - нафиг не надо. достаточно просто под списком форумов выводить последние N тем в них.
еще раз - я прочел тему за вчера, но оставил на сладкое позавчерашнюю. Форум прочитан? Главная не перегружена?
не то. Еще раз распишу варианты. Все это с учетом дайджеста, который очень удобная штука, если уж менять, то с его добавлением. 1) новый юзер. Все темы не прочитаны. пишем только инфу о прочитанных заново темах. поднимаем флаг "не сохраняем нечитанные" пишем в лог прочитанные ветки (пишем ид_последнего поста в лог) 2) нажата кнопка "пометить все прочитанным". Сохраняем дату нажатия кнопки. поднимаем флаг "не сохраняем нечитанные". проверяем темы а) по дате. б) по факту прочтения. (пишем ид_последнего поста в лог) 3) прошел год после нажатия кнопки "пометить все прочитанным" юзер прочел 5к тем, из них 100 сейчас актуальны, остальные читанные и нечитанные утопли. формат хранения полей таблицы с просмотрами - binary или varbinary по 32бит. user_id, topic_id, post_id возможно добавления тех же полей в таблицы users, topics, posts размер имхо получается приемлемый, особенно с учетом дайджеста. данные по неактуальным веткам/юзерам можно скидывать в архивную таблицу и восстанавливать в случае необходимости вопрос как сократить объем инфы по полностью прочитанным веткам. разбить на два запроса и хранить в отдельной таблице? user_id,topic_id
Да, форум прочитан, если ты запомнил, что хочеш что-то ещё прочитать, прочитай это когда будет время, но для движка форума особенности методов прочтения тем различными пользователями не должен иметь значения, сканировать все темы форума в поисках не прочитанных - бессмыслено. Я не читаю 99% тем большинства посещаемых мною форумов.