Созрел я, наконец, до реализации давней идеи. Суть в том, чтобы постинги топиков, к которым давно не было обращений, сбрасывать в отдельную таблицу. А при обращении к ним - перекидывать их снова в основную.
Решение оказалось даже несколько проще, чем я ожидал и серьёзно править в движке нужно только одно место одного файла
Сразу предупреждаю, что готового решения не даю, ибо расписывать до буковки многое просто лень, тем, у кого форумы на сотни тысяч постингов, скорее всего, моих подсказок будет достаточно, а для других это решение бесполезно.
Суть решения такая. Вводим учёт даты последнего чтения топика. Отдельным внешним скриптом скидываем то, к чему давно не было обращений в отдельную таблицу. В движке форума если при чтении из основной таблицы топики не были найдены, то пытаемся перебросить их из архивной в основную.
Итак, по порядку.
0. Делаем бэкап базы. На всякий пожарный.
1. Добавляем к таблице ib_topics новое поле `last_view_date` типа INT.
2. Делаем альтернативную таблицу в БД форума. Внимание, все префиксы у меня не ib_, а ib_! Так что меняйте сами!
code mysql
);
Таблица - фактически копия ib_posts, только выкинуты ненужные индексы.
3. Ищем по файлам строки типа
code text
'set' => 'views=views+1',
и меняем на
code text
'set' => 'views=views+1, last_view_date='.time(),
Т.е. к изменению числа просмотров топика добавляем и время его последнего просмотра. Нужно будет чтобы отделять то, к чему давно не было обращений.
Можно также (полезно, но не обязательно) найти все строки с
code text
'views' => 0,
и приписать после них
code text
'last_view_date' => time(),
это мы впишем дату для создаваемых вновь топиков.
Теперь - главное. Лезем в ips_kernel\class_db_mysql.php
Ищем функцию
function query($the_query, $bypass=0) {
Находим запрос:
code text
$this->query_id = mysql_query($the_query, $this->connection_id);
После него дописываем:
code text
if(preg_match("!ib_posts!",$the_query))
{
if(!mysql_num_rows($this->query_id))
{
if(preg_match("!topic_id=(\d+)!",$the_query,$bal_t_m))
{
$bal_t_fh=fopen("from_archive_move.log","at");
fwrite($bal_t_fh, strftime("%d.%m.%Y %H:%M:%S")."|$the_query\n");
fclose($bal_t_fh);
$bal_t_q = "REPLACE `ib_posts` SELECT * FROM `ib_posts_archive` WHERE `topic_id`={$bal_t_m[1]}";
if(!mysql_query($bal_t_q, $this->connection_id))
$this->fatal_error("mySQL query error: $bal_t_q");
$bal_t_q = "DELETE FROM `ib_posts_archive` WHERE `topic_id`={$bal_t_m[1]}";
if(!mysql_query($bal_t_q, $this->connection_id))
$this->fatal_error("mySQL query error: $bal_t_q");
$this->query_id = mysql_query($the_query, $this->connection_id);
}
}
}
Всё. Должно работать.
Осталось только привести скрипт по архивации постингов:
code php
#!/usr/local/bin/php
<font size=1><xmp>
<?
ini_set('default_charset','utf-8');
$dbh = @mysql_connect("localhost", "<user>", "<password>") or
die ("Could not connect");
$q="SELECT `tid` FROM `ib_topics` WHERE `posts`<>0 AND `last_post`<".(time()-30*86400)." AND `last_view_date`<".(time()-30*86400);
$n=0;
$s=0;
{
$q="REPLACE `ib_posts_archive` SELECT * FROM `ib_posts` WHERE `topic_id`={$row['tid']}";
$q="DELETE FROM `ib_posts` WHERE `topic_id`={$row['tid']}";
if($r)
$n++;
$s+=$r;
}
echo "$n topics / $s posts was moved";
?></xmp></font>
И запускаем этот скрипт, скажем, раз в сутки по CRON'у. Он перебросит все сообщения, к которым не было обращений больше месяца и последний ответ которых старше, чем в 1 месяц в архив.
Да, ещё замечу, что решение это только что реализованное. Возможны какие-то ошибки
Но, во-первых, мы сделали бэкап, а во-вторых, ничего страшного быть тут не должно