Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > PHP: Базы Данных > Ответ на комментарий


Автор: patap 4.4.2011, 11:22
помогите дельным советом, как правильнее реализовать такую вот штуку:

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

Код

[это что-то, что комментирруют]
[igor]: коммент от игоря
[test]: коммент от test
[igor] to [test]: ответ от игоря юзеру test


как это лучше сделать? 

я начал так, когда отвечаем юзеру на коммент, то его ид заносится в поле to_user, но потом понял что не могу достать имя юзера, которому ответили.
т.к если это "комментарий ответ", то нужно в результате вернуть два пользовательских имени.

в принципе можно через временную таблицу, достать во временную таблицу имена юзеров, которым был ответ, а потом сджойнить ее с основным результатом, но не уверен оптимальности.

либо добавить поле в таблицу comments to_username, и записывать в него имя пользователя, которому был ответ, но это будет дублирование данных.. 

в общем такая вот ситуация, может я чего-то не догоняю и тут все намного проще...

Код

CREATE TABLE IF NOT EXISTS `comments` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `item_id` int(11) NOT NULL,
  `user_id` int(11) NOT NULL,
  `to_user` int(11) NOT NULL,
  `content` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=4 ;

--
-- Dumping data for table `comments`
--

INSERT INTO `comments` (`id`, `item_id`, `user_id`, `to_user`, `content`) VALUES
(1, 4, 2, 0, 'агфсл нщг'),
(2, 4, 2, 1, 'коммент для юзера с ид 1 от ид 2'),
(3, 4, 2, 0, 'коммент3');


Код

CREATE TABLE IF NOT EXISTS `users` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `email` varchar(127) NOT NULL,
  `username` varchar(32) NOT NULL DEFAULT '',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uniq_username` (`username`),
  UNIQUE KEY `uniq_email` (`email`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=16 ;

--
-- Dumping data for table `users`
--

INSERT INTO `users` (`id`, `email`, `username`) VALUES
(1, 'igor@gmail.com', 'igor'),
(2, 'test@gmail.com', 'test');

Автор: patap 4.4.2011, 15:10
пока что сделал так:

Код

CREATE TEMPORARY TABLE recipients
SELECT comments.id, users.username AS recipient
FROM comments, users
WHERE comments.item_id = 4 AND comments.to_user = users.id;

SELECT comments.*, users.username, recipients.recipient 
FROM comments JOIN users ON comments.user_id = users.id 
LEFT OUTER JOIN recipients ON recipients.id = comments.id
WHERE comments.item_id = 4


вот результат
Код

id    item_id    user_id     to_user   content                            username        recipient
1     4          2           0         агфсл нщг                          test            NULL
2     4          2           1         коммент для юзера с ид 1 от ид 2   test            igor
3     4          2           0         коммент3                           test            NULL



единственное что беспокоит - это временная таблица, т.к. имя этой таблицы будет генерироваться динамически при каждом запросе на получение комментариев.
Т.е. при каждом запросе будет создаваться уникальная временная таблица, разумеется она после завершения сеанса с БД будет удаляться, но вот к примеру если будет около сотни обращений в один момент или больше, не выйдет ли это боком?

Добавлено через 7 минут и 16 секунд
либо может быть возложить это на плечи PHP...
т.е сделать так:

сначала достать тех юзеров для которых есть сообщения "ответ"
Код

SELECT comments.id, users.username AS recipient
FROM comments, users
WHERE comments.item_id = 4 AND comments.to_user = users.id


потом достать собственно сообщения
Код

SELECT comments.*, users.username
FROM comments JOIN users ON comments.user_id = users.id 
WHERE comments.item_id = 4


ну и обработать это все на стороне PHP... Есть, что у кого посоветовать?

Автор: ksnk 4.4.2011, 15:25
Комменты на комменты - получается дерево. Нужно пилить в сторону "хранение деревьев в базе данных" и применять полученные знания.

Ветка дерева "нулевого" уровня - комментарий на статью. Ветка ненулевого - комментарий на комментарий.

Автор: patap 4.4.2011, 15:48
ksnk, спасибо.

я с деревьями знаком.
В данном случае нет необходимости строить дерево, основная идея в том, что если юзер1 отвечает юзеру2, то это значит, что это сообщение привязано просто к юзеру2, но не к сообщению от юзера2.

т.е. другими словами нужно получить запись, чтобы в ней фигурировало имя юзера которому ты хочешь что-то сказать.
это наподобие того, как на этом форуме, когда пишешь и хочешь вставить чье-то имя в пост - нажимаешь на ник участника и имя вставляется в тело сообщения.

можно было бы, тоже вклеить имя юзера в сообщение, но тогда нужно ограничить юзера в действиях по смене ника

блин, хрень какая-то... smile

ЗЫ а парент ид наверно добалю для сообщения, так про запас.

Автор: Nigel 4.4.2011, 23:37
Какая задача-то? Цитирование сделать как здесь? Тогда просто обрамляешь текст в \[QUOTE\]\[/QUOTE\] и парсишь регулярками.

Автор: ksnk 5.4.2011, 01:54
Цитата(patap @  4.4.2011,  15:48 Найти цитируемый пост)
т.е. другими словами нужно получить запись, чтобы в ней фигурировало имя юзера которому ты хочешь что-то сказать.

Видимо, не просто фигурировало, а еще и искать по нему можно было впоследствии.
Имя юзера вставляется просто в тегах. Чтобы была ссылка на оригинального юзера - нужно добавлять поле в таблицу комментов. А вот что делать, если один комментарий ответ сразу нескольким юзерам?  smile Полей в таблице не резиновое количество...
Слишком сложно получается. 
Сменить ник - не такая уж и криминальная операция, чтобы её стоило запрещать, так что искать следует только по ID пользователя. 
Можно навернуть специальный вид "сообщения" - в начале текстом вставляются ID пользователей в обрамлении специальных символов. Эти символы при выводе вырезаются регулярками, при поиске по ним ищем оператором LIKE. Хотя все равно ерунда какая-то, для большого количества комментариев будет тормозить. Лучше сделать деревья и жить как положено.

Автор: patap 5.4.2011, 09:50
с утра посмотрел на это все, и решил что для моего случая, будет идиальным вариантом - просто лента комментов, без всяких вые..новвот этих вот прибауток smile
все равно спасибо, быть может без советов полез бы в ненужные дебри...

Автор: Vreden 19.6.2011, 13:45
ХМ... Не уверен что суть вопроса мне ясна, но я реализовал коммент на коммент следующим образом, в форме отправки комментария у меня есть скрытое поле со значением CommentAnswer и когда юзер тычет на кнопку "Цитировать", расположенную у каждого комментария, CommentAnswer присваивается ID цитируемого комментария, заносим его в базу и при выводе данного комментария по ID того коммента вытаскиваю имя юзера и все остальные потроха. Ничего зазорного в том, чтобы для этих целей хранить еще одно поле в таблице не вижу.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)