[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Пагинация иерархических данных Closure Table
forza
Добрый день,

В одном проекте использую технику Closure Table для создания древовидных комментариев. До сегодняшнего дня дерево комментариев выводилось полностью. Сейчас стала необходимостью подгружать их (примерно как на пикабу). Не могу понять как сделать правильную сортрировку вложенного дерева на стороне базы данных. В интернете ничего толкового не нашел. Есть одна статья, которая решает проблему добавлением дополнительного поля "ранк", но этот подход мне крайне не нравится (https://coderwall.com/p/lixing/closure-tables-for-browsing-trees-in-sql). Может кто-то сталкивался с подобной проблемой? Как вообще вы решали проблему с пагинацием вложенных комментариев?
Мне не нужна реализация, просто идея или проcтой псевдо-код. Если не хотите делится, то пишите в ПМ. Договоримся.

_____________
Заработок для веб-разработчиков: CodeCanyon
Мое Портфолио
forza
Также, если у кого-то есть реально рабочий код или наработки - пишите, договоримся о цене. Желательно иметь онлайн-демонстрацию.

_____________
Заработок для веб-разработчиков: CodeCanyon
Мое Портфолио
Guest
Цитата (forza @ 24.01.2017 - 14:43)
Есть одна статья, которая решает проблему добавлением дополнительного поля "ранк", но этот подход мне крайне не нравится

Более чем годное решение.
forza
Если сделать поле ранк VARCHAR(255) (больше не получится т.к. упремся в лимит индекса), то максимальная вложенность будет ~23 уровня. Есть пару мест где в данный момент она больше.

_____________
Заработок для веб-разработчиков: CodeCanyon
Мое Портфолио
Ron
Наверное в данном случае будет правильнее использовать nested sets. Нам не нужны сложные операции над деревом, такие как перенос узла или сабтри. Кроме того мы эту возможность сильно испортили добавлением path enumeration, который называется гордым словом rank. Хоть и децл видоизменен, но это он.

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

forza
Ну насчет выбора способа хранения. Изначально выводились рутовые комментарии + 1 дочерний с кнопкой раскрыть все дерево. Потом перешли просто на дерево. Для самой первой задачи паттерн подходил идеально.

Теперь нужно что-то в виде пагинации.
По статистике (на данный момент) 1-2 левела комментариев 75%, остальные 3 и более. Есть единичные в виде 20+.. В общем общий объем таблицы в десятки раз меньше чем мог бы быть в теории.

Есть активные топики, где по 500+ комментариев. При добавлении новых с nested sets надо делать 500+ апдейтов, в то время как с closure table 1-5 в среднем инсертов.

Если у кого-нибудь есть хоть какие-то наработки кода для хранения древовидных структур с сортировкой и пагинацией (кроме несте сетс) - пишите, о цене договоримся. Не важно, даже если вы используете другой подход (например adjacency list) - для меня портировать из старой структуры в новую не составит труда.

_____________
Заработок для веб-разработчиков: CodeCanyon
Мое Портфолио
Ron
Цитата (forza @ 24.01.2017 - 23:49)
При добавлении новых с nested sets надо делать 500+ апдейтов, в то время как с closure table 1-5 в среднем инсертов.

Смотря в какую часть дерева добавляется узел.
Цитата
для меня портировать из старой структуры в новую не составит труда.

Ну так портируй в nested sets, потестируй. =) Чем сидеть ждать у моря погоды. )
Michael
Цитата (Ron @ 24.01.2017 - 23:52)
Цитата (forza @ 24.01.2017 - 23:49)
При добавлении новых с nested sets надо делать 500+ апдейтов, в то время как с closure table 1-5 в среднем инсертов.

Смотря в какую часть дерева добавляется узел.

Для древовидных комментов, он может добавляться куда угодно

_____________
There never was a struggle in the soul of a good man that was not hard
forza
Да сделал уже временное решение в виде 3 запросов:
1. Общее количество рутовых комментариев.
2. С помощью лимит/оффсет выбираю Х рутовых комментариев.
3. Вытаскиваю их ветки и на ПХП строю дерево.

Конечно на каждой странице общее количество комментариев разное, но это не так заметно при бесконечном скролле.

Как вы понимаете это не то, что я хочу, поэтому мое предложение остается в силе. Если у кого то найдется решение - пишите. О цене договоримся.

_____________
Заработок для веб-разработчиков: CodeCanyon
Мое Портфолио
Ron
Цитата (Michael @ 25.01.2017 - 09:08)
Для древовидных комментов, он может добавляться куда угодно

Совершенно верно. Посчитай частоту, выведи среднее, там будет далеко не 500+ строк затронуто в UPDATEe. Например, добавить коммент в конец дерева т.е. новый коммент, всего лишь 2 строки в апдейте и одна в инсёрте.

Цитата (forza @ 25.01.2017 - 11:34)
Вытаскиваю их ветки и на ПХП строю дерево.

Вот это гораздо хуже, если, конечно, не используется кэш. Количество запросов на чтение опережает запись на порядки. По производительности такое решение в итоге скорее всего гораздо затратнее, чем nested sets.

Конечно, если заморочиться с кэшом (намек!), ситуация может сильно поменяться. wink.gif Хотя, перестраивать кэш, или сделать апдейт 200-т строк, что окажется эффективнее больщущий вопрос. Мне вот почему-то кажется СуБД победит. biggrin.gif И по скорости и по отсутствию гемора. biggrin.gif

forza
Пожалуй соглашусь. Сделал так.

К классической модели добавил 2 поля: `tree` и `parent_id`. теперь каждый отдельный комментарий это одно маленькое деревце.
Кроме того поле `parent_id` помогает сэкономить пачку запросов и дает возможность при подгрузки комментариев вставлять их в нужные узлы ДОМ дерева.

Ставим индекс на 3 поля (`entity_id`, `tree`, `lft`) и простым запросом загружаем части комментариев отсортированные уже в нужном порядке.

SELECT * FROM comments WHERE entity_id = 20 ORDER BY tree, lft LIMIT 10, 20


_____________
Заработок для веб-разработчиков: CodeCanyon
Мое Портфолио
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.