![]() |
![]() |
![]()
Post
#1
|
|
Grupa: Zarejestrowani Postów: 247 Pomógł: 11 Dołączył: 5.09.2009 Ostrzeżenie: (0%) ![]() ![]() |
Jak mamy w bazie danych tabelę z kolumnami:
id | id_parent | order To dodając nowy element użytkownik wybiera z select listy rodzica oraz z drugiej select listy liczbę reprezentującą wagę/kolejność dodawanego elementu w stosunku do innych na tym samym poziomie. A jak mamy w bazie danych tabelę ze strukturą charakterystyczną dla nested set: id | left | right To użytkownik dodając nowy element wybiera z select listy rodzica, ale w jaki sposób może ustalić wagę/kolejność nowo dodawanego elementu w stosunku do innych na tym samym poziomie ? Nie bardzo wiem jak umożliwić użytkownikom ustalenie kolejności. |
|
|
![]() |
![]()
Post
#2
|
|
Grupa: Zarejestrowani Postów: 952 Pomógł: 154 Dołączył: 20.01.2007 Skąd: /dev/oracle Ostrzeżenie: (0%) ![]() ![]() |
Przecież left i right dzieci tego samego węzła są ułożone w kolejności, w jakiej te elementy występują:
Kod SELECT ... ORDER BY `left`
|
|
|
![]()
Post
#3
|
|
Grupa: Zarejestrowani Postów: 247 Pomógł: 11 Dołączył: 5.09.2009 Ostrzeżenie: (0%) ![]() ![]() |
No dobra, ale jak rodzic ma dwójkę potomków a ja chcę wstawić miedzy nie jeszcze jednego potomka albo przed nimi, albo po nich to w jaki sposób mam to umożliwić użytkownikowi ?
|
|
|
![]()
Post
#4
|
|
Grupa: Zarejestrowani Postów: 6 476 Pomógł: 1306 Dołączył: 6.08.2006 Skąd: Kraków Ostrzeżenie: (0%) ![]() ![]() |
Musisz odpowiednio pozmieniać wartości left/right sporej części drzewa. W sieci masz mnóstwo przykładów na to jak przemieszczać poszczególne gałęzie w takim modelu drzewka. google: moving nested set, move nested set - czy cokolwiek zwierającego "nested set" i coś związanego z ruchem.
|
|
|
![]()
Post
#5
|
|
Grupa: Zarejestrowani Postów: 247 Pomógł: 11 Dołączył: 5.09.2009 Ostrzeżenie: (0%) ![]() ![]() |
Tylko takie przenoszenie gałęzi oznacza wielokrotny update co moze prowadzic do anomalii.
|
|
|
![]()
Post
#6
|
|
Grupa: Zarejestrowani Postów: 782 Pomógł: 153 Dołączył: 21.07.2010 Ostrzeżenie: (0%) ![]() ![]() |
A gdzie jest napisane że relacyjne bazy danych najlepiej nadają do tworzenia drzew? Jeśli rzeczywiście chcesz ustabilizować sobie strukturę drzewa to napisz jakiś wyzwalacz który po dodaniu dziecka uaktualni strukturę drzewa - bo wysyłanie kilkunastu zapytań w tym celu mija się z celem (IMG:style_emoticons/default/smile.gif)
|
|
|
![]()
Post
#7
|
|
Grupa: Moderatorzy Postów: 15 467 Pomógł: 1451 Dołączył: 25.04.2005 Skąd: Szczebrzeszyn/Rzeszów ![]() |
Cytat gałęzi oznacza wielokrotny update co moze prowadzic do anomalii. Blokowanie tabeli albo transakcja. |
|
|
![]()
Post
#8
|
|
Grupa: Zarejestrowani Postów: 6 476 Pomógł: 1306 Dołączył: 6.08.2006 Skąd: Kraków Ostrzeżenie: (0%) ![]() ![]() |
Cytat Tylko takie przenoszenie gałęzi oznacza wielokrotny update co moze prowadzic do anomalii. Nie. Oznacza to jednokrotny update i insert. Ale jak już erix zauważył: transakcje.
|
|
|
![]()
Post
#9
|
|
Grupa: Zarejestrowani Postów: 247 Pomógł: 11 Dołączył: 5.09.2009 Ostrzeżenie: (0%) ![]() ![]() |
A ma ktos gotowe zapytania do przenoszenia poddrzewa ? Bo cos nie do konca mi dziala ten skrypt do przenoszenia galezi:
Ten post edytował wiewiorek 5.08.2010, 20:13:44 |
|
|
![]()
Post
#10
|
|
Grupa: Zarejestrowani Postów: 782 Pomógł: 153 Dołączył: 21.07.2010 Ostrzeżenie: (0%) ![]() ![]() |
@wiewiorek - prawdopodobnie (nie testowałem dogłębnie tych procedur) poniżej masz kod do przenoszenia gałęzi.
Zapoznałem się bliżej z nested set (nie wiedziałem że istnieje taki model drzewa w sql (IMG:style_emoticons/default/winksmiley.jpg) i wychodzi na to że jest to bardzo fajna rzecz. Poprzednicy mówili o stosowaniu transakcji - zgadzam się, jednak jeśli tylko użytkownik ma możliwość tworzenia procedur to zarządzanie tym drzewem staje się bajecznie proste. Niestety w tym przypadku nie możemy użyć wyzwalaczy (może gdyby pokombinować, nie wiem). Przy budowaniu procedur korzystałem z gotowców z tej strony oraz tego rozwiązania w przypadku przenoszenia gałęzi. Templatka z procedurami była przygotowywana dla tabeli "nested_category", dla innych trzeba przepisać nazwę. Tak wygląda użycie:
Templata z procedurami jest taka:
Ten post edytował everth 7.08.2010, 00:08:54 |
|
|
![]()
Post
#11
|
|
Grupa: Zarejestrowani Postów: 247 Pomógł: 11 Dołączył: 5.09.2009 Ostrzeżenie: (0%) ![]() ![]() |
Dzięki everth (IMG:style_emoticons/default/smile.gif)
Mi w nested set nie podoba się to, że trudno wskazać położenie nowo dodawanego potomka w stosunku do innych potomków - bo najwygodniej dodaje się potomka przed innymi potomkami albo po innych potomkach. Bo jak np. mamy coś takiego: zwierzęta / | \ pies kot chomik To w jaki sposób dać użytkownikowi możliwość dodania 'bocian' po 'kot' ? Trudno powiedzieć, najłatwiej po prostu zawsze dodawać nowy element w tym samym miejscu - czyli na końcu - po 'chomik' lub na początku - przed 'pies' lub zrobić dla użytkownika select listę z opcjami wyboru położenia nowo dodawanego elementu: 'na początku' i 'na końcu'. No bo jak inaczej ? Zrobić dla użytkownika select listę z opcjami dla nowo dodawanego elementu: -umieść przed pies -umieść po pies -umieść przed kot -umieść po kot -umieść przed chomik -umieść po chomik to by było bez sensu. Dlatego wskazywanie położenia nowo dodawanego elementu w nested set jest utrudnione i praktycznie ograniczone do położenia przed lub po innych elementach na tym samym poziomie. |
|
|
![]()
Post
#12
|
|
Grupa: Zarejestrowani Postów: 1 332 Pomógł: 294 Dołączył: 12.10.2008 Skąd: Olkusz Ostrzeżenie: (0%) ![]() ![]() |
To w jaki sposób dać użytkownikowi możliwość dodania 'bocian' po 'kot' ? Trudno powiedzieć, najłatwiej po prostu zawsze dodawać nowy element w tym samym miejscu - czyli na końcu - po 'chomik' lub na początku - przed 'pies' lub zrobić dla użytkownika select listę z opcjami wyboru położenia nowo dodawanego elementu: 'na początku' i 'na końcu'. No bo jak inaczej ? Zrobić dla użytkownika select listę z opcjami dla nowo dodawanego elementu: -umieść przed pies -umieść po pies -umieść przed kot -umieść po kot -umieść przed chomik -umieść po chomik to by było bez sensu. Dlatego wskazywanie położenia nowo dodawanego elementu w nested set jest utrudnione i praktycznie ograniczone do położenia przed lub po innych elementach na tym samym poziomie. domyślnie to najlepiej dodawać na końcu (jak to tradycyjnie wszystko na końcu ląduje)... jednak jeśli chcesz taką listę robić i możliwość wyboru to zauważ, że powtórzyły się miejsca wyboru na tej liście... najnaturalniej by było jeśli chcesz listę rozwijalną to razem z grupowaniem gdzie wymieniasz elementy na tym samym poziomie a do wyboru jest tylko miejsce lub wymieniasz elementy normalnie nie w liście za koleją i miedzy tymi elementami masz input typu ratio domyślnie z zaznaczoną ostatnią opcją (czyli na końcu)... poza tym w tabeli wg. mnie warto sobie to połączyć z parent_id (szybciej znajdziesz elementy na tym samym poziomie jeśli jest bardzo wiele poziomów... samą wartość parent_id możesz sobie wygenerować np. jednym zapytaniem:
zaś wartości poprzypisywać w dodatkowej kolumnie np. tym:
z kolei samo przenoszenie gałęzi już istniejących to jakoś wydaje mi się, że prościej skorzystać z tabel tymczasowych do tego celu przeznaczonych - ale jak kto woli... ogólnie fajnie jest to wszystko opisane na tym blogu: Me vs. tree czyli drzewka w MySQL i PHP Ten post edytował zegarek84 7.08.2010, 11:37:14 |
|
|
![]() ![]() |
![]() |
Aktualny czas: 23.08.2025 - 16:01 |