2010-02-28 2 views
4

Я пытаюсь написать систему комментариев, где люди могут комментировать другие комментарии, и они отображаются в виде рекурсивных потоков на странице. (Reddit's Система комментариев - пример того, чего я пытаюсь достичь), однако я смущен тем, как реализовать такую ​​систему, которая не будет очень медленной и дорогостоящей вычислительной.Реализация рекурсивных комментариев в PHP/MySQL

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

ответ

5

Попробуйте использовать модель вложенного набора. Он описан в Managing Hierarchical Data in MySQL.

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

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

1

Вот another site, содержащий информацию об этом методе + некоторый исходный код.

1

Я нормально работаю с родительской - дочерней системой.

Например, рассмотрим следующий:

Таблица комментария ( CommentID, PageId, идентификатор пользователя, комментарий [, ParentID] )

ParentID является внешним ключом к CommentID (от та же таблица), которая является необязательной (может быть NULL).

Для выбора комментарии использовать это для «корня» комментарий:

SELECT * FROM comments WHERE pageID=:pageid AND parentID IS NULL 

И это для ребенка:

SELECT * FROM comments WHERE pageID=:pageid AND parentID=:parentid 
+0

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

1

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

Вот ссылки:

http://www.evanpetersen.com/index.php/item/php-and-mysql-recursion.html

и

http://www.evanpetersen.com/index.php/item/php-mysql-revisited.html

1

Это только предложение, но так как я столкнулся с той же проблемой прямо сейчас, Как насчет добавить (int) и поле глубины в таблице комментариев, и обновить его при вставке новых комментариев.

Поле последовательности будет служить для упорядочивания комментариев. И поле глубины указывает уровень рекурсии комментария.

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

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

1

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

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

Я заметил (к сожалению), что я хотел, чтобы комментарии к корню упорядочивались по дате по убыванию, НО Я хотел ответить на комментарии к заказу date asc !! Paradoxal !!

Таким образом, вложенная модель не помогла мне уменьшить количество запросов.

Вот мое решение:

Создать комментарий таблицу со следующими полями:

ID
article_id
parent_id (обнуляемая)
date_creation
электронной
whateverYouLike
последовательностью
глубины

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

Последовательность - это реальное ключевое поле, это своего рода эмуляция вложенной модели.

Каждый раз, когда вы вставляете новый комментарий root, он кратен x. Я выбираю x = 1000, что в основном означает, что у меня может быть 1000 максимальных вложенных комментариев (это единственный недостаток, который я нашел для этой системы, но этот предел можно легко изменить, этого достаточно для моих потребностей сейчас).

Последний комментарий к корню должен быть с наибольшим порядковым номером.

Теперь ответные комментарии: у нас есть два случая: ответ за комментарий root или ответ для ответа.

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

Я не ожидаю, что вы все это поймете, так как я не очень хороший объяснитель, , но я надеюсь, что это может дать вам новые идеи. (По крайней мере, это сработало для меня лучше, чем вложенная модель = меньше запросов, что является реальной целью).

Смежные вопросы