2010-07-27 2 views

ответ

2

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

+0

это определенно хорошая идея, я интересно, если это может нарушить в любом случае, скажем, в обновлении, удалить и т.д. 1st мысли нет, shld быть в порядке. У меня просто странное чувство, что это может сломаться как-то –

+0

Для удаления это не имеет значения (предполагается, что если вы удалите узел, вы также удалите все его дети). Если вы перемещаете узел, вам просто нужно изменить его родительский идентификатор в дополнение к его значениям lft и rgt. – GWW

4

Как вы обнаружили, это не так просто в дизайне MPTT. Вы знаете, как получить все потомки:

SELECT * FROM tree WHERE lft BETWEEN 2 AND 11; 

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

SELECT * FROM tree t1 WHERE t1.lft BETWEEN 2 AND 11 
    AND NOT EXISTS (SELECT * FROM tree t2 WHERE t2.lft > 2 AND t2.lft < 11 
        AND t1.lft > t2.lft AND t1.rgt < t2.rgt); 
+0

Я действительно не получаю часть 't1.lft> t2.lft И t1.rgt

+0

Да, я бы пошел с родительский столб. Это делает его проще. Я просто дал решение, которое является «чистым» дизайном MPTT. –

+0

Проголосовали, потому что я думаю, что это довольно элегантное решение. Благодаря! :) – PPvG

1

Получил такое же требование, гораздо более простой способ будет

select * from tree t1 
where t1.nodeleft > 1 
and 1 in (select count(*) from tree where tree.nodeleft < t1.nodeleft and tree.noderight > t1.noderight) 
+0

Работает отлично. Спасибо за этот снимок кода. – kr1zmo

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

  • Нет связанных вопросов^_^