Задать вопрос
Sanu0074
@Sanu0074

Как правильно организовать извлечение дочерних комментариев в древовидной структуре?

Я делаю комментарии, они должны быть древовидны и у них есть всего одна степень вложенности (прим. комменты на ютубе).

Структура таблицы

CREATE TABLE `_fx_comments` ( 
`id` int(11) NOT NULL AUTO_INCREMENT, 
`pid` int(11) DEFAULT NULL, 
`sender` int(11) NOT NULL, 
`recipient` int(11) DEFAULT NULL, 
`target` varchar(150) NOT NULL, 
`eid` int(11) NOT NULL, 
`date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, 
`text` text, 
`rateTrue` int(7) NOT NULL DEFAULT '0', 
`rateFalse` int(7) NOT NULL DEFAULT '0', 
`resource` text, 
`approve` int(1) NOT NULL DEFAULT '1', 
`isDel` int(1) NOT NULL DEFAULT '1', 
PRIMARY KEY (`id`), 
KEY `pid` (`pid`), 
KEY `sender` (`sender`), 
KEY `recipient` (`recipient`), 
KEY `target` (`target`), 
KEY `eid` (`eid`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


eid - id элемента которому принадлежат комментарии, pid - id коммента-родителя

Основная задача которую мне нужно решить - это извлечь допустим последние 10 комментов у которых pid IS NOT NULL,
и както смотреть если у текущего коммента есть дочерние - то извлечь их (два дочерних - последние добавленные).

Но теперь как-то надо извлечь последние два дочерних.....
Может быть косяк в структуре БД, буду рад выслушать ваши советы!

_UPD_
На данный момент есть такой ужасный вариант решения задачи:
SELECT fx_cmt.id,fx_cmt.pid,fx_cmt.eid,fx_cmt.sender,fx_cmt.recipient,fx_cmt.date,fx_cmt.text,fx_cmt.rateTrue,fx_cmt.rateFalse,fx_cmt.resource,
        fx_u.fx_login AS senderLogin, fx_u2.fx_login AS recipientLogin,
        (SELECT COUNT(fx_cmt_count.id)  FROM _fx_comments fx_cmt_count WHERE fx_cmt_count.pid = fx_cmt.id) AS countChilds,

         fx_cmt_l.id AS lcId, fx_cmt_l.pid AS lcPid, fx_cmt_l.eid AS lcEid, fx_cmt_l.sender AS lcSender, fx_cmt_l.recipient AS lcRecipient, fx_cmt_l.date AS lcDate,
             fx_cmt_l.text AS lcText, fx_cmt_l.rateTrue AS lcRateTrue, fx_cmt_l.rateFalse AS lcRateFalse, fx_cmt_l.resource AS lcResource,

         fx_cmt_pl.id AS plcId, fx_cmt_pl.pid AS plcPid, fx_cmt_pl.eid AS plcEid, fx_cmt_pl.sender AS plcSender, fx_cmt_pl.recipient AS plcRecipient, fx_cmt_pl.date AS plcDate,
             fx_cmt_pl.text AS plcText, fx_cmt_pl.rateTrue AS plcRateTrue, fx_cmt_pl.rateFalse AS plcRateFalse, fx_cmt_pl.resource AS plcResource,

         fx_u_l.fx_login AS lcSenderLogin, fx_u2_l.fx_login AS lcRecipientLogin,
         fx_u_pl.fx_login AS plcSenderLogin, fx_u2_pl.fx_login AS plcRecipientLogin

FROM _fx_comments AS fx_cmt 

INNER JOIN _fx_users fx_u ON fx_u.id = fx_cmt.sender
LEFT JOIN _fx_users fx_u2 ON fx_u2.id = fx_cmt.recipient

LEFT JOIN _fx_comments fx_cmt_l ON fx_cmt_l.id = (SELECT id FROM _fx_comments AS c WHERE c.pid = fx_cmt.id  ORDER BY date DESC LIMIT 0,1)
LEFT JOIN _fx_comments fx_cmt_pl ON fx_cmt_pl.id = (SELECT id FROM _fx_comments AS c WHERE c.pid = fx_cmt.id  ORDER BY date DESC LIMIT 1,1)

LEFT JOIN _fx_users fx_u_l ON fx_u_l.id = fx_cmt_l.sender
LEFT JOIN _fx_users fx_u2_l ON fx_u2_l.id = fx_cmt_l.recipient
LEFT JOIN _fx_users fx_u_pl ON fx_u_pl.id = fx_cmt_pl.sender
LEFT JOIN _fx_users fx_u2_pl ON fx_u2_pl.id = fx_cmt_pl.recipient

WHERE fx_cmt.eid = 1

Но этот вариант хоть и работает, но он ужасен, поэтому нужно более корректное решение....
  • Вопрос задан
  • 72 просмотра
Подписаться 1 Оценить Комментировать
Пригласить эксперта
Ответы на вопрос 1
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы