2010-08-16 2 views
3

У меня есть таблица (id, parent_id, data), где parent_id указывает на другую строку в одной таблице (или равна нулю).Запросы, чтобы получить всех предков/потомков дерева в db?

Существует ли стандартный способ запроса (1) всех предков определенного идентификатора и (2) всех потомков определенного идентификатора?

Я тоже делаю это в DBIx::Class, поэтому, если есть самый удобный способ сделать это с помощью этого модуля (или другого), я тоже хотел бы услышать об этом.

EDIT: уточнить - все родители = все предки, все дети = все потомки.

+0

Просто родители/дети или все предки/потомки? Кроме того, какой вкус SQL вы используете? –

+0

Глядя, чтобы быть агностиком SQL; наша разработка db - SQLite, но производство, вероятно, будет MySQL. – Carl

+0

См. Также http://en.wikipedia.org/wiki/Nested_set_model – reinierpost

ответ

1

Похоже, мы собираемся перейти с DBIx::Class::Tree::AdjacencyList на данный момент. Это почти все, что я искал (к сожалению, нет результатов предков, но мы можем обойти это, приблизившись к вопросам, которые нам нужно задать с другого направления).

Однако @ ответ Grrrr заставляет меня думать, и мы можем добавить отдельную таблицу + модуль (id, record_type, record_ancestors), что бы присоединить к нашим моделям, которые имеют parent_id колонок и обеспечивает ancestors ResultSet (в основном, делая search_rs, где идентификатор в раскол соответствующей серии предков по разделителю w/e, который мы выбираем). Это справедливая работа, чтобы получить такой набор результатов, поэтому мы, вероятно, только отправимся туда, если найдем вопросы, где действительно нецелесообразно спрашивать «это ребенок родителя x» и действительно нужно «это родитель ребенок х "?

EDIT: или, возможно, мы будем использовать DBIx::Class::Tree::Mobius - хотя это выглядит так, что просмотр таблицы будет непонятным.

+1

Было бы очень легко добавить метод «предков» к вашим классам Row, добавив его непосредственно в свои классы «Result» или создав новый компонент, который подклассы AdjacencyList и добавит необходимый вам метод. Или, может быть, вы можете остановиться на # dbix-классе и поговорить с нами о просто добавлении функции самому AdjacencyList; это кажется довольно разумным. – hobbs

+0

@hobbs: мой соавтор по этому проекту предложил патч, добавив набор результатов предков в AdjacencyList (не уверен, какой идентификатор он публикует, и у него не хватает SO rep, чтобы сделать свой собственный комментарий). – Carl

3

Это очень зависит от вкуса SQL, который вы используете.

В Oracle вы можете использовать конструкцию START WITH id = yourid CONNECT BY PRIOR id = parent_id. В PostgreSQL вы можете использовать функцию connectby('tablename', 'id', 'parent_id', 'id', value, 0).

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

Есть много примеров этой техники можно найти в Интернете, самый последний из которых я видел, который также имеет дело с DBIx::Class, можно найти здесь: http://blogs.perl.org/users/ovid/2010/05/threaded-forum-sql.html

+0

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

+0

eeeeeh ... кроме каскадной части. – Carl

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