Adam W.

Adam W. senior php
developer, Symfony

Temat: nested set - naprawa

witam,

ma ktoś pomysł jak naprawić strukturę drzewa nested sets?
Wojciech Sznapka

Wojciech Sznapka CTO @ STS Zakłady
Bukmacherskie

Temat: nested set - naprawa

a co konkretnie jest popsute? :>
Adam W.

Adam W. senior php
developer, Symfony

Temat: nested set - naprawa

Wojciech Sznapka:
a co konkretnie jest popsute? :>


struktura, struktura drzewa jest popsuta;)

czyli lft i rgt.
po prostu były usunięte rekordy nie poprzez mechanizm do usuwania z drzewa tylko tak o na żywca. po usunięciu struktura trochę się zdezorganizowała.

konto usunięte

Temat: nested set - naprawa

temporary table i szybki skrypt w php wstawiający całe drzewo od nowa.
jak masz tego dużo to alter table ... engine = memory ;-)
Adam W.

Adam W. senior php
developer, Symfony

Temat: nested set - naprawa

Michał Wujas:
temporary table i szybki skrypt w php wstawiający całe drzewo od nowa.
jak masz tego dużo to alter table ... engine = memory ;-)

dzięki. mimo zmęczenia domyślałem się, że tak to można zrobić;)
tylko teraz kwestia tego szybkiego skryptu php.

konto usunięte

Temat: nested set - naprawa

spoko, nested trees sa dobrze opisane, dasz rade =)

konto usunięte

Temat: nested set - naprawa

Adam W.:
czyli lft i rgt.
po prostu były usunięte rekordy nie poprzez mechanizm do usuwania z drzewa tylko tak o na żywca. po usunięciu struktura trochę się zdezorganizowała.

Usuwałeś tylko liście czy też jakieś wierzchołki nie bądące liścimi?

W tym pierwszym przypadku drzewo w ogóle nie powinno się popsuć. W tym drugim - zależy co chcesz zrobić z osieroconymi poddrzewami, ale podejrzewam, że skończy się na ręcznym naprawianiu wierzchołek po wierzchołku.

Temat: nested set - naprawa

Adam W.:
witam,

ma ktoś pomysł jak naprawić strukturę drzewa nested sets?

W swoich bazach mam w pierony takich drzew więc profilaktycznie do każdego mam procedurę składowaną, która je odbudowuje. Z resztą używam ich na bieżąco wywołując przy usuwaniu rekordów.

Tutaj kod jednej z nich:


CREATE `procSubunitsTreeRebuild`(in parUnitId bigint unsigned)
BEGIN
create temporary table tempSubunits
(NestedLevel bigint unsigned default null,
NestedLeft bigint unsigned default null,
NestedRight bigint unsigned default null,
key(UnitId),
key(NestedParent),
key(SequenceNumber))
engine = memory
select UnitId,
NestedParent,
SequenceNumber
from tblSubunits
where UnitId in (select UnitId
from tblUnits
where UpperUnitId = parUnitId);

begin
declare varNestedLeft bigint unsigned default 1;
declare varNestedRight bigint unsigned;
declare varNestedLevel bigint unsigned default 0;
declare varUnitId bigint unsigned;
declare varDone bit default 1;
declare cur cursor for
select UnitId
from tempSubunits
where NestedParent is null
order by SequenceNumber;
declare continue handler FOR sqlstate '02000' set varDone = 0;

open cur;
fetch cur into varUnitId;
while varDone do
update tempSubunits
set NestedLevel = 0,
NestedLeft = varNestedLeft,
NestedRight = varNestedLeft + 1
where UnitId = varUnitId;

set varNestedLeft = varNestedLeft + 2;
fetch cur into varUnitId;
end while;
close cur;

build_tree: while true do
begin
declare cur2 cursor for
select UnitId
from tempSubunits
where NestedLevel = varNestedLevel;

set varDone = 1;

open cur2;
fetch cur2 into varUnitId;

if not varDone then
leave build_tree;
end if;

while varDone do
begin
declare varChildId bigint unsigned;
declare cur3 cursor for
select UnitId
from tempSubunits
where NestedParent = varUnitId
order by SequenceNumber;

select NestedRight
into varNestedRight
from tempSubunits
where UnitId = varUnitId;

open cur3;
fetch cur3 into varChildId;
while varDone do
update tempSubunits
set NestedRight = NestedRight + 2
where NestedRight >= varNestedRight;

update tempSubunits
set NestedLeft = NestedLeft + 2
where NestedLeft > varNestedRight;

update tempSubunits
set NestedLevel = varNestedLevel + 1,
NestedLeft = varNestedRight,
NestedRight = varNestedRight + 1
where UnitId = varChildId;

set varNestedRight = varNestedRight + 2;
fetch cur3 into varChildId;
end while;
close cur3;

set varDone = 1;
fetch cur2 into varUnitId;
end;
end while;
close cur2;

set varNestedLevel = varNestedLevel + 1;
end;
end while build_tree;

update tempSubunits
join tblSubunits on tempSubunits.UnitId = tblSubunits.UnitId
set tblSubunits.NestedLevel = tempSubunits.NestedLevel,
tblSubunits.NestedLeft = tempSubunits.NestedLeft,
tblSubunits.NestedRight = tempSubunits.NestedRight;
end;
drop temporary table tempSubunits;
END



Po lekkim dostosowaniu epwnie zrobi czego potrzebujesz.
Adam W.

Adam W. senior php
developer, Symfony

Temat: nested set - naprawa

Wojciech Malinowski:
Adam W.:
czyli lft i rgt.
po prostu były usunięte rekordy nie poprzez mechanizm do usuwania z drzewa tylko tak o na żywca. po usunięciu struktura trochę się zdezorganizowała.

Usuwałeś tylko liście czy też jakieś wierzchołki nie bądące liścimi?

W tym pierwszym przypadku drzewo w ogóle nie powinno się popsuć. W tym drugim - zależy co chcesz zrobić z osieroconymi poddrzewami, ale podejrzewam, że skończy się na ręcznym naprawianiu wierzchołek po wierzchołku.

z tego widzę zostały usunięte liście - rodzic ma teraz przykładowo lft = 19, rgt = 25. nie ma teraz liście między 19 a 25.

konto usunięte

Temat: nested set - naprawa

Adam W.:
z tego widzę zostały usunięte liście - rodzic ma teraz przykładowo lft = 19, rgt = 25. nie ma teraz liście między 19 a 25.

Ale w takim razie drzewo zachowało swoją strukturę i nie musisz nic poprawiać.

Przyjrzyj się jednak, czy Twoje procedury są w porządku, bo nie bardzo sobie umiem wyobrazić jakikolwiek układ wierzchołków w których left i right rodzica to 19 i 25.

Temat: nested set - naprawa

Wojciech Malinowski:
Adam W.:
z tego widzę zostały usunięte liście - rodzic ma teraz przykładowo lft = 19, rgt = 25. nie ma teraz liście między 19 a 25.

Ale w takim razie drzewo zachowało swoją strukturę i nie musisz nic poprawiać.


Nieprawda. W drzewie nested set jeżeli zrobisz right - left - 1 to powinieneś otrzymać liczbę potomków. W opisanym zdegenerowanym drzewie nie będzie to prawdą.
Adam W.

Adam W. senior php
developer, Symfony

Temat: nested set - naprawa

Wojciech Małota:
Wojciech Malinowski:
Adam W.:
z tego widzę zostały usunięte liście - rodzic ma teraz przykładowo lft = 19, rgt = 25. nie ma teraz liście między 19 a 25.

Ale w takim razie drzewo zachowało swoją strukturę i nie musisz nic poprawiać.


Nieprawda. W drzewie nested set jeżeli zrobisz right - left - 1 to powinieneś otrzymać liczbę potomków. W opisanym zdegenerowanym drzewie nie będzie to prawdą.

dokładnie tak. teraz mi wskazuje, że ta kategoria (bo o kategorie chodzi;) ma ileś tam dzieci a to nie jest prawdą, bo te dzieci zostały usunięte ręcznie z bazy.

konto usunięte

Temat: nested set - naprawa

Wojciech Małota:
Ale w takim razie drzewo zachowało swoją strukturę i nie musisz nic poprawiać.

Nieprawda. W drzewie nested set jeżeli zrobisz right - left - 1 to powinieneś otrzymać liczbę potomków. W opisanym zdegenerowanym drzewie nie będzie to prawdą.

Dla ścisłości: wynik musisz podzielić jeszcze przez 2.

Chodziło mi jednak o coś innego. Wiadomo, że te indeksy trzeba przebudować, tak samo jak trzeba je przebudować przy każdej modyfikacji (zmiana/usunięcie/dodanie) wierzchołka w drzewie. Z tym nie dyskutuje. Podejrzewałem, że Adam o tym wie i że ma gotowe procedury to tej czynności.

Co jednak wskazałem to to, że struktura drzewa nie została zniszczona. Można odpalić procedurę przebudowania drzewa i wszystko będzie działać.

Zauważyłem też, że Adam ma coś mocno popsute gdzie indziej, bo nie da się uzyskać normalnie wierzchołka o left = 19 i right = 25.

Mam nadzieję, że wyraziłem się jasno tym razem.

Temat: nested set - naprawa

Wojciech Malinowski:
Wojciech Małota:
Ale w takim razie drzewo zachowało swoją strukturę i nie musisz nic poprawiać.

Nieprawda. W drzewie nested set jeżeli zrobisz right - left - 1 to powinieneś otrzymać liczbę potomków. W opisanym zdegenerowanym drzewie nie będzie to prawdą.

Dla ścisłości: wynik musisz podzielić jeszcze przez 2.

Nie musisz :-). Chyba, że używasz innego nested tree niż ja.
Zauważyłem też, że Adam ma coś mocno popsute gdzie indziej, bo nie da się uzyskać normalnie wierzchołka o left = 19 i right = 25.

To prawda. Left zawsze jest nieparzyste, a right zawsze parzyste.
Ewentualnie na odwrót. To zależy czy ktoś numeruje od 1 czy od 0.

konto usunięte

Temat: nested set - naprawa

Ale w takim razie drzewo zachowało swoją strukturę i nie musisz nic poprawiać.
Nieprawda. W drzewie nested set jeżeli zrobisz right - left - 1 to powinieneś otrzymać liczbę potomków. W opisanym zdegenerowanym drzewie nie będzie to prawdą.
Dla ścisłości: wynik musisz podzielić jeszcze przez 2.
Nie musisz :-). Chyba, że używasz innego nested tree niż ja.

Zaintrygowałeś mnie tym swoim nested sets.

Ja używam (oczywiście tylko kiedy potrzebuję - bo są lepsze reprezentacje drzewa) tej metody: http://www.dbf.pl/faq/tresc.html?rozdzial=1#o1_9 (metoda 3). Jakiej Ty używasz?

Temat: nested set - naprawa

Wojciech Malinowski:
Ale w takim razie drzewo zachowało swoją strukturę i nie musisz nic poprawiać.
Nieprawda. W drzewie nested set jeżeli zrobisz right - left - 1 to powinieneś otrzymać liczbę potomków. W opisanym zdegenerowanym drzewie nie będzie to prawdą.
Dla ścisłości: wynik musisz podzielić jeszcze przez 2.
Nie musisz :-). Chyba, że używasz innego nested tree niż ja.

Zaintrygowałeś mnie tym swoim nested sets.

Uhm. Mea culpa. Biję się w pierś - trzeba dzielić przez dwa :-).
Adam W.

Adam W. senior php
developer, Symfony

Temat: nested set - naprawa

Wojciech Malinowski:
Wojciech Małota:
Ale w takim razie drzewo zachowało swoją strukturę i nie musisz nic poprawiać.

Nieprawda. W drzewie nested set jeżeli zrobisz right - left - 1 to powinieneś otrzymać liczbę potomków. W opisanym zdegenerowanym drzewie nie będzie to prawdą.

Dla ścisłości: wynik musisz podzielić jeszcze przez 2.

Chodziło mi jednak o coś innego. Wiadomo, że te indeksy trzeba przebudować, tak samo jak trzeba je przebudować przy każdej modyfikacji (zmiana/usunięcie/dodanie) wierzchołka w drzewie. Z tym nie dyskutuje. Podejrzewałem, że Adam o tym wie i że ma gotowe procedury to tej czynności.

Co jednak wskazałem to to, że struktura drzewa nie została zniszczona. Można odpalić procedurę przebudowania drzewa i wszystko będzie działać.

zgadza się struktura wydaje się być dobra. tylko te liczby trzeba pozmieniać.
skopiowałem te dane do nowej kategorii, już z dobrą strukturą.
teraz tylko z powrotem do tabeli głównej.
Zauważyłem też, że Adam ma coś mocno popsute gdzie indziej, bo nie da się uzyskać normalnie wierzchołka o left = 19 i right = 25.

Mam nadzieję, że wyraziłem się jasno tym razem.

bardzo jasne:) gratuluję bystrego oka. te liczby podałem z kosmosu.

dzięki za podpowiedzi.
Adam W.

Adam W. senior php
developer, Symfony

Temat: nested set - naprawa

Wojciech Małota:
To prawda. Left zawsze jest nieparzyste, a right zawsze parzyste.
Ewentualnie na odwrót. To zależy czy ktoś numeruje od 1 czy od 0.

czy jesteś tego pewien na 100% ?
bo właśnie patrzę teraz w tabeli i widzę, że różnie z tym bywa.

to wydaje się być niemożliwe, bo np:
lft | rgt
1 | 452
2 | 7
3 | 4

konto usunięte

Temat: nested set - naprawa

Adam W.:
czy jesteś tego pewien na 100% ?
bo właśnie patrzę teraz w tabeli i widzę, że różnie z tym bywa.

to wydaje się być niemożliwe, bo np:
lft | rgt
1 | 452
2 | 7
3 | 4

Myślę, że Wojtkowi chodziło o to, że zawsze jedna z liczb jest parzysta, a druga nieparzysta - ale tylko w ramach jednej pary (left, right), a nie w ramach całej tabeli.

Temat: nested set - naprawa

Wojciech Malinowski:
Adam W.:
czy jesteś tego pewien na 100% ?
bo właśnie patrzę teraz w tabeli i widzę, że różnie z tym bywa.

to wydaje się być niemożliwe, bo np:
lft | rgt
1 | 452
2 | 7
3 | 4

Myślę, że Wojtkowi chodziło o to, że zawsze jedna z liczb jest parzysta, a druga nieparzysta - ale tylko w ramach jednej pary (left, right), a nie w ramach całej tabeli.


Tak właśnie. Nie wyraziłem się jasno.

Następna dyskusja:

NAPRAWA,MONTAZ URZADZEN GAZ...




Wyślij zaproszenie do