Změna pořadí prvků modelu nested set

Změna pořadí prvků modelu nested set
« kdy: 23. 07. 2020, 11:31:59 »
Uz par dnu se snazim zmenit poradi prvku v nested set modelu, ale bez uspechu.
Interval <7;16> se snazim preradit v <6;23> na prvni misto

Kód: [Vybrat]
id name lft rgt
1 ROOT 1 24
2 1 6 23
4 2 4 5
5 3 2 3
7 1.2 21 22
8 1.3 19 20
9 1.4 17 18
11 100 7 16
12 100.1 14 15
14 100.2 12 13
15 100.3 10 11
16 100.4 8 9

- pro presouvane prvky plati 0-x
- nasledovne vsechno prvky v intervalu <6;23>  snizit o velikost mnoziny  <7;16>

Kód: [Vybrat]
id name lft rgt
1 ROOT 1 24
2 1 6 23
4 2 4 5
5 3 2 3
7 1.2 11 12
8 1.3 9 10
9 1.4 7 8
11 100 -7 -16
12 100.1 -14 -15
14 100.2 -12 -13
15 100.3 -10 -11
16 100.4 -8 -9

V poslednim kromu se nevim rady jak prvky dostat do nasledujiciho umisteni


Kód: [Vybrat]
id name lft rgt
1 ROOT 1 24
2 1 6 23
4 2 4 5
5 3 2 3
7 1.2 11 12
8 1.3 9 10
9 1.4 7 8
11 100 13 22
12 100.1 14 15
14 100.2 16 17
15 100.3 18 19
16 100.4 20 21
« Poslední změna: 23. 07. 2020, 14:53:06 od Petr Krčmář »


Re:Zmena poradi prvku nested set modelu
« Odpověď #1 kdy: 23. 07. 2020, 11:58:52 »
Začněte tím, že napíšete, o jaké prostředí se jedná – nějaký programovací jazyk, knihovna, databáze? Jinak obecně set (množina) označuje skupinu prvků, které nemají definované pořadí. Jste si jist, že vaše prostředí používá set v jiném významu a pořadí je tam definované?

Re:Zmena poradi prvku nested set modelu
« Odpověď #2 kdy: 23. 07. 2020, 12:14:27 »
Mnozina je ulozena v MYSQL. Pomoci PHP pak provadim zmeny. Prostredi ve kterem se vysledny list pouziva nyni potrebuje resit i razeni prvku. Pridani a odebirani prvku je snadne. Razeni uz tolik ne. Jako posledni moznost me napadlo pridat sloupec urcujici poradi prvku v ramci rozsahu rodice.

Vysledek by mohl vypadat takto:

Kód: [Vybrat]
id name lft rgt   prio
1 ROOT 1 24     1
2 1 6 23     1
4 2 4 5      2
5 3 2 3      3
7 1.2 21 22     2
8 1.3 19 20     3
9 1.4 17 18     4
11 100 7 16     5
12 100.1 14 15     1
14 100.2 12 13     2
15 100.3 10 11     3
16 100.4 8 9      4

ale snad se to da resit i bez toho

Re:Zmena poradi prvku nested set modelu
« Odpověď #3 kdy: 23. 07. 2020, 13:13:46 »
Vaším cílem je tedy reprezentovat stromovou (nebo jen dvouúrovňovou?) strukturu, kde si uživatel bude moci ručně seřadit prvky pod konkrétním uzlem? Pokud chcete použít nested set model, nezbývá vám při aktualizaci nic jiného, než prvky přečíslovat. Pokud budou aktualizace relativně častá operace, zvolil bych spíš jinou reprezentaci stromu. Přidat sloupec určující pořadí prvků v rámci rozsahu rodiče nedává smysl – tahle informace už je zakódovaná v left a right.

Re:Zmena poradi prvku nested set modelu
« Odpověď #4 kdy: 23. 07. 2020, 13:30:40 »
Jde o stromovou strukturu, ktera reprezentuje navigaci na webu. Vnoreni prvku muze byt neomezene. Zmena poradi polozek se deje jen v pripade, kdy to vyzaduje spravce. S tim postupem precislovani si prave nevim rady.


Re:Zmena poradi prvku nested set modelu
« Odpověď #5 kdy: 23. 07. 2020, 14:09:29 »
Musíte vždy projít kompletně určitý podstrom a ten přečíslovat. Pokud budete pořadí měnit vždy jen prohozením dvou prvků, přečíslujete jen ta dva prvky (a jejich podstromy). Pokud uživateli umožníte třeba 4. prvek přetáhnout rovnou na 1. místo, nebo přerovnat celou jednu úroveň a pak nové pořadí jako prvek uložit, musíte přečíslovat celý podstrom společného rodičovského prvku. Přečíslování děláte, jako byste to čísloval poprvé – procházíte prvky v uživatelem určeném pořadí a postupně je číslujete.

Re:Zmena poradi prvku nested set modelu
« Odpověď #6 kdy: 23. 07. 2020, 14:43:48 »
Pokud mam nasledujici znazorneni:

Kód: [Vybrat]
|-------[2-15]----[16-21]-----[22-25]-------|
1         A        B          C             26

poradi prvku je zobrazeno nasledovne: (vyssi rozsah ma prednost)
1.C
2.B
3.A

pozadovany je:
1.A
2.B
3.C

Ale ten postup pro prepocet urcit nedovedu


Re:Zmena poradi prvku nested set modelu
« Odpověď #7 kdy: 23. 07. 2020, 15:09:23 »
Třeba jsem jen blbý a neznalý, ale mě to připadá už od začátku nějak divně navržené.

Pokud do tabulky ukládám stromovou strukturu dal bych tam položky:
id - číselné, unikátní, neměnné, začínající od 1
parentId - root položky mají 0, ostatní jejich nadřazenou položku
localOrder - lokální pořadí v rámci jedné podskupiny
jakékoliv další položky, pro řazení nevýznamné

Pro zobrazení celého stromu najednou buď použiju rekurzi, nebo bych si musel dodefinovat složený globalOrder (složený ze všech localOrder položek od dotyčného prvku až do rootu) a ten při změně pořadí vždy aktualizovat všem prvkům podstromu posunutého prvku.
Pokud budu chtít cokoliv přetřídit v rámci některé podskupiny, použiju jako filtr parentId (identifákátor podskupiny) a tam jednoduchým algoritmem přeházím localOrder hodnoty.

A. F.

Re:Změna pořadí prvků modelu nested set
« Odpověď #8 kdy: 23. 07. 2020, 15:19:50 »
Uz par dnu se snazim zmenit poradi prvku v nested set modelu, ale bez uspechu.
Interval <7;16> se snazim preradit v <6;23> na prvni misto

Když jsem tuto úlohu onehdá řešil, tak jsem si to srovnal na tyto čtyři scénáře:
1/ přidání prvku
2/ odebrání prvku
3/ přesun prvku dolů
4/ přesun prvku nahoru

Ve tvém případě to bude tedy přesun nahoru, jestli jsem to dobře pochopil (když tak mě oprav).

To znamená
- vytvořit místo, kam se přesunou prvku
- přesunout prvky

To znamená zjistit jak široký je uzel který přesouváš, to znamená rgt - lft, to znamená jeden SELECT = size.
To znamená zjistit offset přesouvaného uzlu, to znamená jeden SELECT = offset.
Následně UPDATE, které přečísluje všechny uzly, kterou jsou větší jak začátek umístění o size (včetně uzlu, který budeš přesouvat).
Následně UPDATE, které přečísluje přesouvaný uzel: původní lft = lft - offset. (Offset si můžeš vypočítat na začátku, nebo po přesunu - jde oboje.)


Plus samozřejmě by se to dalo různě optimalizovat.

A. F.

Re:Zmena poradi prvku nested set modelu
« Odpověď #9 kdy: 23. 07. 2020, 15:23:30 »
Třeba jsem jen blbý a neznalý, ale mě to připadá už od začátku nějak divně navržené.
To co tam má navržené je takzvané Traverzování kolem stromu. Celkem úspěšná technika jak do ploché databáze uložit strom. Má spousta i výkonnostních výhod pro čtení. Horší je zápis, ale je to spíše náročné na hlavu. Po odlazení už to funguje moc pěkně.

PS: Nejsem si jist, zda v tomto případě je či není nutný znát rodiče, tedy parent_id.

Re:Změna pořadí prvků modelu nested set
« Odpověď #10 kdy: 23. 07. 2020, 15:56:02 »
Uz par dnu se snazim zmenit poradi prvku v nested set modelu, ale bez uspechu.
Interval <7;16> se snazim preradit v <6;23> na prvni misto

Když jsem tuto úlohu onehdá řešil, tak jsem si to srovnal na tyto čtyři scénáře:
1/ přidání prvku
2/ odebrání prvku
3/ přesun prvku dolů
4/ přesun prvku nahoru

Ve tvém případě to bude tedy přesun nahoru, jestli jsem to dobře pochopil (když tak mě oprav).

To znamená
- vytvořit místo, kam se přesunou prvku
- přesunout prvky

To znamená zjistit jak široký je uzel který přesouváš, to znamená rgt - lft, to znamená jeden SELECT = size.
To znamená zjistit offset přesouvaného uzlu, to znamená jeden SELECT = offset.
Následně UPDATE, které přečísluje všechny uzly, kterou jsou větší jak začátek umístění o size (včetně uzlu, který budeš přesouvat).
Následně UPDATE, které přečísluje přesouvaný uzel: původní lft = lft - offset. (Offset si můžeš vypočítat na začátku, nebo po přesunu - jde oboje.)


Plus samozřejmě by se to dalo různě optimalizovat.

Misto v cilovem rodici mam ale nevim jak tam ty prvky presunout. Prvky oznacene pro presun maji minusovou hodnotu (na zacatku prispevku je to videt) Prakticky provedu odebrani mnoziny a pak znovu pridani. Zadny delete ani insert, protoze id radku je primarni klic a ten se nesmi zmenit kvuli relacim.


A. F.

Re:Změna pořadí prvků modelu nested set
« Odpověď #11 kdy: 23. 07. 2020, 16:23:23 »
Uz par dnu se snazim zmenit poradi prvku v nested set modelu, ale bez uspechu.
Interval <7;16> se snazim preradit v <6;23> na prvni misto

Když jsem tuto úlohu onehdá řešil, tak jsem si to srovnal na tyto čtyři scénáře:
1/ přidání prvku
2/ odebrání prvku
3/ přesun prvku dolů
4/ přesun prvku nahoru

Ve tvém případě to bude tedy přesun nahoru, jestli jsem to dobře pochopil (když tak mě oprav).

To znamená
- vytvořit místo, kam se přesunou prvku
- přesunout prvky

To znamená zjistit jak široký je uzel který přesouváš, to znamená rgt - lft, to znamená jeden SELECT = size.
To znamená zjistit offset přesouvaného uzlu, to znamená jeden SELECT = offset.
Následně UPDATE, které přečísluje všechny uzly, kterou jsou větší jak začátek umístění o size (včetně uzlu, který budeš přesouvat).
Následně UPDATE, které přečísluje přesouvaný uzel: původní lft = lft - offset. (Offset si můžeš vypočítat na začátku, nebo po přesunu - jde oboje.)


Plus samozřejmě by se to dalo různě optimalizovat.

Misto v cilovem rodici mam ale nevim jak tam ty prvky presunout. Prvky oznacene pro presun maji minusovou hodnotu (na zacatku prispevku je to videt) Prakticky provedu odebrani mnoziny a pak znovu pridani. Zadny delete ani insert, protoze id radku je primarni klic a ten se nesmi zmenit kvuli relacim.

Aha. Tak ten problém bude s těmi minusovými hodnotami.

Nene, já neříkám, že máš něco mazat. Budeš používat jen UPDATE. Také žádné odebrání z množiny a její přidání. Jen upravuješ hodnotu lft a rgt.

Takže: nejdřív všechno, včetně těch prvků určených pro přesun přečísluješ nahoru. Ke každému lft a rgt přičteš šířku toho uzlu. Nebudeš tomu dávat záporné hodnoty ani nic podobného.
Pak vezmeš ten uzel a opět přečísluješ lft a rgt směrem dolu tak aby zapadl do připravené díry.
A pak (na to jsem v původním příspěvku zapomněl) zacelíš díru která vznikla po přesunu toho prvku a to tím, že opět přečísluješ lft a rgt dolu o velikost šířku posouvaného uzlu.

Pracuješ s UPDATE a nejvíc řešíš správné WHERE, aby si přečísloval tu správnou množinu uzlů. V prvním případě počínaje prvním uzlem, který chceš stěhovat až do konce. V druhém případě jen uzly, které chceš stěhovat. A ve třetím případě jen uzly od původně posledního rgt stěhované prvku plus jedna až do konce.

Re:Změna pořadí prvků modelu nested set
« Odpověď #12 kdy: 23. 07. 2020, 17:15:23 »
Kód: [Vybrat]
Takže: nejdřív všechno, včetně těch prvků určených pro přesun přečísluješ nahoru. Ke každému lft a rgt přičteš šířku toho uzlu. Nebudeš tomu dávat záporné hodnoty ani nic podobného.
Pak vezmeš ten uzel a opět přečísluješ lft a rgt směrem dolu tak aby zapadl do připravené díry.
A pak (na to jsem v původním příspěvku zapomněl) zacelíš díru která vznikla po přesunu toho prvku a to tím, že opět přečísluješ lft a rgt dolu o velikost šířku posouvaného uzlu.

Pokud si to predstavuju spravne tak pri presnym postupu je vysledek nula. Nic se nemeni

A. F.

Re:Změna pořadí prvků modelu nested set
« Odpověď #13 kdy: 23. 07. 2020, 17:22:30 »
Kód: [Vybrat]
Takže: nejdřív všechno, včetně těch prvků určených pro přesun přečísluješ nahoru. Ke každému lft a rgt přičteš šířku toho uzlu. Nebudeš tomu dávat záporné hodnoty ani nic podobného.
Pak vezmeš ten uzel a opět přečísluješ lft a rgt směrem dolu tak aby zapadl do připravené díry.
A pak (na to jsem v původním příspěvku zapomněl) zacelíš díru která vznikla po přesunu toho prvku a to tím, že opět přečísluješ lft a rgt dolu o velikost šířku posouvaného uzlu.

Pokud si to predstavuju spravne tak pri presnym postupu je vysledek nula. Nic se nemeni

To určitě ne. Proč si to myslíš?

Re:Změna pořadí prvků modelu nested set
« Odpověď #14 kdy: 23. 07. 2020, 17:53:39 »
Kód: [Vybrat]
name      lft rgt
 1          1   8 
 1.3        2   3
 1.2        4   5
 1.1        6   7

Prvek 1.3 budu chtit zobrazovat jako prvni. Je nutno ho dat za prvek 1.1. Prvky s vetsim intervalem maji vyssi hodnotu pri zobrazovani.
Sirka uzlu je 3-2+1=2


Takže: nejdřív všechno, včetně těch prvků určených pro přesun přečísluješ nahoru. Ke každému lft a rgt přičteš šířku toho uzlu.

Kód: [Vybrat]
name      lft rgt
 1          3   10 
 1.3        4   5
 1.2        6   7
 1.1        8   9
Pak vezmeš ten uzel a opět přečísluješ lft a rgt směrem dolu tak aby zapadl do připravené díry.

Kód: [Vybrat]
name      lft rgt
 1          3   10 
 1.3        2   3
 1.2        6   7
 1.1        8   9

A pak (na to jsem v původním příspěvku zapomněl) zacelíš díru která vznikla po přesunu toho prvku a to tím, že opět přečísluješ lft a rgt dolu o velikost šířku posouvaného uzlu.

Kód: [Vybrat]
name      lft rgt
 1          1   8 
 1.3        2   3
 1.2        4   5
 1.1        6   7
« Poslední změna: 23. 07. 2020, 17:55:44 od korabro »