![]() |
Задавайте вопросы, мы ответим
Вы не зашли.
Здраствуйте.
Вопрос в том как "это" соединить или сократить, а то получается 1 + колво форумов * 2 запросов только для одного вывода главной страницы. Время обработки небольшое довольно таки, но и нагрузка на сервер пока просто не велика.
Есть запрос:
SELECT cat.cid, cat.name as cname, forum.fid, forum.name, forum.desc, forum.c, COUNT( DISTINCT topic.id ) AS topics, COUNT( DISTINCT post.pid ) AS posts FROM cat LEFT JOIN forum ON cat.cid = forum.c AND cat.gid = forum.gid AND cat.gid = forum.gid LEFT JOIN post ON post.fid = forum.fid AND cat.gid = post.gid AND cat.gid = forum.gid LEFT JOIN topic ON post.fid = topic.fid AND cat.gid = topic.gid AND topic.gid = forum.gid WHERE forum.gid = 1 (например) GROUP BY forum.name ORDER BY forum.c, forum.fid ASC LIMIT 0, 100
он выбирает список форумов, категорий и количество тем и сообщений в них для скрипта форума. С него я делаю главную страницу форума, но потом пришла мысль добавить например "последнее сообщение в форуме", то есть название темы, и ссылка на неё с временм последнего сообщения в ней.
и идет цикл с разбором первого запроса и в нём подзапросы пришлось сделать
$query = "SELECT aid,pid,time,tid FROM `forum`.`post` WHERE gid=".$gid." AND fid=".$id." ORDER BY `time` DESC LIMIT 0,1"; $res = mysql_query($query); $res = mysql_fetch_assoc($res); $q = "SELECT name FROM `forum`.`topic` WHERE id=".$res['tid']; $r = mysql_query($q); $r = mysql_fetch_assoc($r); $id = ид форума который сейчас выводиться.
Структура таблиц:
--
-- Структура таблицы `cat`
--
CREATE TABLE `cat` (
`gid` tinyint(4) NOT NULL COMMENT 'Номер группы где категория',
`cid` tinyint(3) NOT NULL COMMENT 'Ид категории в форуме группе',
`name` varchar(50) NOT NULL COMMENT 'Имя категории',
`st` varchar(4) NOT NULL default 'OPEN' COMMENT 'Приватность',
KEY `id` (`cid`,`name`)
) ENGINE=MyISAM DEFAULT CHARSET=cp1251;
--
-- Структура таблицы `forum`
--
CREATE TABLE `forum` (
`gid` int(5) NOT NULL COMMENT 'Номер группы гдбе форум',
`c` tinyint(2) NOT NULL COMMENT 'Категория где этот форум',
`fid` tinyint(2) NOT NULL COMMENT 'Ид форума в группе (не зависит от категории и считается (все форумы+1))',
`name` varchar(50) NOT NULL COMMENT 'Название форума',
`desc` varchar(250) NOT NULL COMMENT 'Описание форума',
`st` enum('OPEN','CLOSED') default 'OPEN' COMMENT 'Статус/приватность форума'
) ENGINE=MyISAM DEFAULT CHARSET=cp1251;
--
-- Структура таблицы `post`
--
CREATE TABLE `post` (
`gid` int(4) NOT NULL COMMENT 'Номер группы где пост',
`fid` tinyint(4) NOT NULL COMMENT 'Номер форума где пост',
`tid` int(4) NOT NULL COMMENT 'Номер топика, где пост',
`pid` int(4) NOT NULL auto_increment COMMENT 'УНИКАЛЬНЫЙ для всего сайта ид поста',
`aid` int(4) default NULL COMMENT 'Ид автора поста',
`text` text NOT NULL COMMENT 'Текст сообщения',
`time` datetime NOT NULL COMMENT 'Дата/время добавления сообщения в форум',
PRIMARY KEY (`pid`)
) ENGINE=MyISAM DEFAULT CHARSET=cp1251 AUTO_INCREMENT=120 ;
--
-- Структура таблицы `topic`
--
CREATE TABLE `topic` (
`gid` tinyint(4) NOT NULL COMMENT 'Номер группы, где топик',
`id` tinyint(4) NOT NULL auto_increment COMMENT 'Уникальный для всего сайта ид топика',
`fid` tinyint(4) NOT NULL COMMENT 'Ид форума, где топик',
`aid` tinyint(4) NOT NULL COMMENT 'Ид автора топика',
`name` varchar(100) NOT NULL COMMENT 'Название темы',
`date` datetime NOT NULL COMMENT 'Дата создания темы',
`lasttime` datetime NOT NULL,
`st` enum('OPEN','CLOSE','PRIVATE','TRASH') default NULL COMMENT 'Приватность/статус темы',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=cp1251 AUTO_INCREMENT=22 ;Может надо UNION? Но я не умею его использовать.
Неактивен

Для того, чтобы показывать последнее сообщение на форуме имеет смысл денормализовать таблицы. То есть добавить lastlostid в таблицу forum и следить за его обновлением.
Можно использовать тот факт, что более новые сообщения имеют и больший номер
SELECT fid, MAX(tid) FROM `forum`.`post` WHERE gid=".$gid. "GROUP BY fid";
Но в этом случае для определения времени последнего сообщения придется использовать подзапрос.
Неактивен

С другой стороны, подзапрос по ключу должен выполняться достаточно быстро..
Неактивен
Хм... интерестно. На другом форуме мне тоже посоветовали хранить просто как можно больше "готовых" данных, чтобы увеличить производитльность. В частности мои COUNT'ы заменить на число которое, при создании темы/сообщения + 1 и в админке если что сделать уже пересчет.
Спасибо за ответы, буду думать.
Неактивен

А всегда ищется баланс между хранением избыточных данных и скоростью выполнения запроса.
Иногда бывает выгоднее пожертвовать небольшим количеством места под избыточную колонку.
Неактивен