проверка значения в дереве n-depth?

У меня есть два объекта, post и category которая является отношением 1:n .

У меня есть справочная таблица с двумя столбцами, post_id , category_id

Таблица categories имеет столбец id столбец status и столбец parent_id

Если категория является дочерним элементом другой категории (n-depth), то она parent_id не является нулевым.

Если категория находится в сети, ее статус равен 1, в противном случае – 0.

Мне нужно выяснить, видно ли сообщение.

Это требует:

Класс Foreach, соединенный с почтовым parent_id дерево к корневому узлу (до того, как категория имеет parent_id == null ), если какая-либо из этих категорий имеет status 0, тогда этот путь считается автономным.

Если какой-либо путь находится в сети, сообщение считается видимым, иначе оно скрыто.

Единственный способ, которым я могу это сделать (как полу-псевдокод), – это:

 function visible(category_ids){ categories = //select * from categories where id in(category_ids) online = false foreach(categories as category){ if(category.status == 0) continue; children = //select id from categories where parent_id = category.id if(children) online = visible(children) } return online } categories = //select c.id from categories c join posts_categories pc on pc.category_id = c.id where pc.post_id = post.id post.online = visible(categories) 

Но это может быть много запросов sql, есть ли лучший способ?

Solutions Collecting From Web of "проверка значения в дереве n-depth?"

Если вложенные наборы не являются опцией, я знаю следующее:

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

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

Кроме того, если данные не упорядочены, вы можете создать древовидную структуру из (unsorted) запроса всех строк, как указано в ответе на массив Nested. Третий уровень исчезает . Никакой рекурсии не требуется, и вы получаете структуру, которую вы можете легко вывести, тогда я должен был бы рассмотреть это для вывода <ul>/<li> html style в другом ответе.

  • Ответ Как я могу преобразовать серию отношений parent-child в иерархическое дерево?
  • Ответ на вопрос Как получить вложенный список HTML из массива массивов объектов?

Классическая база данных против компиляции памяти. То, что вы делаете, – это построить дерево с листьями в нем. Чтобы построить дерево, вам нужна рекурсивная петля из листьев. Исходя из базы данных, существует 2 сценария:

  1. Создайте дерево рекурсивным с запросом для каждого листа. Вы сохраняете 1 дерево в памяти. Это то, что вы делаете.
  2. Получите плоскую структуру из базы данных и создайте рекурсивное дерево в памяти. У вас есть плоское дерево и реальное дерево в памяти. Это ваш альтернативный путь.

Что лучше зависит от многих вещей: вашего оборудования (доступ к диску против памяти), размер дерева для обозначения двух.