[PHP][MySQL] Kasowanie podkategorii

0

Tabela kategorie wyglada nastepujaco:

id | id_nadrzednej | opis

1 | 0 | ...
2 | 1 | ...
5 | 1 | ...
7 | 2 | ...

Takie wpisy w tabeli oznaczaja, ze kategoria id=1 posiada dwie podkategorie: id=2 i id=5, natomiast kategoria id=2 posiada tylko jedna podkategorie id=7. Mam nadzieję, ze w miarę wyjaśniłem.
I teraz, kiedy kasuję wpis id=1, chciałbym żeby zostały skasowane wszystkie kategorie podrzedne, czyli w tym wypadku kategorie id=2 i id=5, oraz id=7 (bo id=7 jest podrzedna do kategorii id=2 ktora zostanie skasowana). Dla jasności dodam, że chodzi tutaj o takie kasowanie jak np. kasowanie struktury katalogów na dysku - czyli wystarczy wykasowac jeden katalog, a wszystko co sie w nim znajdowalo, razem z podkatalogami, zostanie usunięte.

Problem jest taki, ze nie wiem jak zralizowac takie kasowanie w oparciu o php i mysql. Moglbym to zrealizowac za pomoca rekurencji, ale czy istnieje jakas funkcja ktora zwraca wiersze ktore zostaly usuniete z bazy? A moze istnieje jeszcze prostszy sposob na realizacje tego zadania?

Dzieki za wszystkie sugestie

0

dobrym rozwiazanem by bylo jakbys utworzysz dodatkowa tabele ktora grupowalaby elementy z tabeli ktora zawiera nadrzedne i podrzedne elementy w ten sposob ze dla kazdego elementu nadrzednego tworzylaby grupe o tym samum ID i przypisywala kazdy element podrzedny do tej grupy dzieki temu pozniej moglbys jednym zapytaniem usunac cale drzewo jakie powstalo wczesniej oczywiscie dodawanie wtedy byloby bardziej zlozone ale za to usuwanie realizowane mysle jednym zapytaniem maks dwoma. To jak pozniej operujesz na tabelach zalezy od wczesniejszego ich zaprojektowania.

0

Ja jednak mimo wszystko postawiłem na rekurencję - kasowałem katalog, następnie wyszukiwałem podkatalogi, które kasowałem, następnie dla każdego katalogu wyszukiwałem znowu podkatalogi które kasowałem itd...
Szybkość tego rowiązania na pewno nie jest rewelacyjna, ale dla tak małej bazy jaką tworzę powinna być wystarczająca

0

Witam,

też mam problem z tym usuwaniem podkategorii.
mógłby ktoś podzielić się kawałkiem kodu, który to usuwa?

pozdrawiam

0

To podchodzi pod triggera, najlepiej nałożyć triggera na DELETE i niech trigger kasuje podkategorie.


CREATE TRIGGER on_del BEFORE DELETE ON tabela
FOR EACH ROW 
BEGIN 
DELETE FROM tabela WHERE parentid = OLD.id 
END 

chyba jakoś tak czy podobnie to by było, no ale mysql5 musi być.

0

łomatko :O

a nie mozecie tego zrobic PO PROSTU jednym zapytaniem? o_O

dodajecie tabele np. "path", gdzie dajecie jako text wszystkie kategorie nadrzedne (w razie potrzeby wlacznie z biezaca) - "|0|1|2|7|" potem wywalenie, edycja, wyswietlenie sciezki czy cokolwiek, to tylko jedno zapytanie

0
tomkiewicz napisał(a)

łomatko :O

a nie mozecie tego zrobic PO PROSTU jednym zapytaniem? o_O

dodajecie tabele np. "path", gdzie dajecie jako text wszystkie kategorie nadrzedne (w razie potrzeby wlacznie z biezaca) - "|0|1|2|7|" potem wywalenie, edycja, wyswietlenie sciezki czy cokolwiek, to tylko jedno zapytanie

"dodajecie tabele" rozumiem że miało być dodajecie pole.
Jak by zatem wyglądało zapytanie usuwania kategorii wraz z całą gałęzią podkategorii ?

DELETE FROM TABELA WHERE path LIKE '%|2|%' ?

Można niby i tak, ale trzeba dodatkowo dbać o to żeby path być zawsze poprawny, także pozwolę sobie zacytować "łomatko" ;). Jeśli przeniosę kategorię do innej podkategorii, to będę musiał updatować wszystkie path'y w całej podgałęzi, dobrze myślę?

0

tak pole - przejezyczenie

"dbać o to żeby path być zawsze poprawny" - a to jakis problem? Jezeli sie obawiasz o spojnosc danych, to wystarczy transakcje dac, usuwanie dokladnie tak, jak napisales... Jak chcesz miec jeszcze pewniejsza pewnosc, odpalasz crona o 3 w nocy i przelatujesz baze na poprawnosc

chyba jedyna wada sposobu, to wlasnie przenoszenie, ale wydaje mi sie, ze da sie to zrobic 2-3 zapytaniami (obciecie sciezki kategorii do sciezek wzglednych, doklejenie nowej lokacji na poczatek). Nawet jesli nie, to taka operacja zabiera porownywalna ilosc czasu co np. wyswietlenie fragmentu duzego drzewa (jezeli nie mozesz calego trzymac w pamieci). Co czesciej wykonujesz na kategoriach - przenoszenie, czy wyswietlanie? :>

Owszem - Twoje rozwiazanie jest bardziej eleganckie, ale moze przyczynic sie do padu serwera przy wiekszych i czesto odwiedzanych serwisach :P. A wiem co mowie - ostatnio poprawialem ksiazkowo-"wzorcowo" napisana wyszukiwarke, ktorej nie dawal sobie rady dedykowany - obciazenie procesora spadlo z ~30% do ulamkow procenta (na wykresie prosta linia +/- 1px). Poza tym jak wszystko opiszesz ladnie na obiektach, to i tak sie nie pogubisz w sqlu

0
tomkiewicz napisał(a)

tak pole - przejezyczenie
Nawet jesli nie, to taka operacja zabiera porownywalna ilosc czasu co np. wyswietlenie fragmentu duzego drzewa (jezeli nie mozesz calego trzymac w pamieci). Co czesciej wykonujesz na kategoriach - przenoszenie, czy wyswietlanie? :>

Ok, wyświetlanie gałęzi większych drzew będzie szybsze i już bez 2 zdań zgadzam się że 1000 razy częściej będzie wykonywane wyświetlanie.
Rozumiem, że chodzi o wyświetlenie gałęzi np kategorii o ID=56 tak:
SELECT pola FROM kategotie WHERE path LIKE '%56%', przyznaję, że ciekawy pomysł.

Natomiast zastanawia mnie czy można to jakoś wykorzystać do generowania drzewa wyników wyszukiwania, powiedzmy, że mam kategorie produktów i chcę wyszukać produkty tańsze niż 200zł i chcę wyświetlić tylko te kategorie, które zawierają znalezione produkty (oczywiście kategorie nadrzędne też w tym momencie muszą być rysowane żeby można był dotrzeć niżej)

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.