9 komentářů k článku Ukládáme hierarchická data v databázi – III:

    1. Petr

      Re: mazání v MPTT stromu

      No tady jde asi o to, ze ke kazde polozce ve stromu potrebuju smazat taky polozku z jine tabulky, tak asi proto.

      1. alancox

        Re: mazání v MPTT stromu

        A kde je problém?

        1) delete …. where polozka_id in (select polozka_id from ….between … and …)
        2) delete from strom where strom_id between … and …

          1. Roman Svoboda

            Re: mazání v MPTT stromu

            Autorovo řešení mazání ve foreach cyklu mi přijde zbytečně neoptimální.
            Pokud se nepletu, pro každého potomka ( $descendants ) v uvedeném příkladu zasílán jednu query na DELETE (viz: dibi::query(„DELETE FROM [mptt] WHERE [id] = %i“, $one[‚id‘]); ), což při počtu např. 1000 potomků znamená 1001 dotazů na db.
            Tudíž se mi zdá lepší výše uvedené řešení (to v prvním příspěvku), které používá 1 query na DELETE ať už mažeme jakýkoli počet potomků.
            Současně díky cizím klíčům a cascade delete jsou mazány i referencující položky v jiných tabulkách.

            Z trochu jiného soudku, netuší někdo, jak napsat query tak, aby posunula UZEL stromu (vč. jeho podstromu) níže ve stejné úrovni?
            Tzn. prohodit jej s následujícím uzlem (pokud má následníka).
            Znamená to přepočítat left a right obou těch uzlů, zatím se mi však nepodařilo najít ten správný algoritmus, fungují mi pouze posuny uzlů směrem vzhůru ( na stejné úrovni).

            1. LukasS

              Re: mazání v MPTT stromu

              My to řešili obecným přesunem ve stromu. Tzn. že dovedeme přesunout jakýkoliv uzel kamkoliv. Z hlediska prohození dvou uzlů na stejné úrovni to není nejoptimálnější řešení, ale funguje to dobře. K většímu rozdílu ve výkonu mezi nejoptimálnější a naší verzi dojde pokud vpravo od přesouvaných položek je hodně uzlů.

              Pokud by jste chtěl modifikovat pouze lft/rgt přesouvaných uzlů a jejich potomků, musel by jste řešit problém chvilkové duplicity lft/rgt přesouvaných stromů a nebo dočasně jeden strom přesouvaného uzlu odklidit mimo aktuální rozsah (např. použít záporná čísla).

              Vymyslet to by asi nebyl problém, ale u nás to byla jen podmnožina celkového problému přesunu uzlů. Stejně jsme potřebovali řešit obecné přesuny, takže jsme vyřešili přesuny a optimalizaci nechali na příště ;-). Výkonostní problémy máme nyní jinde (např přidávání uzlu do stromu pokud má strom 100k položek).

  1. Čelo

    knihovna

    Nakonec pro Vás mám lahůdku – vytvořil jsem vám knihovnu pro práci s MPTT…. já ji tam prostě nevidím :)

  2. ArchE

    Flattened tree navigation
    alter table TREE add column NodePath VARCHAR(1024)
    insert into TREE (NodeId, NodeName, NodePath) values(newId, newName, parentPath + sprintf(‚%5d“,newId))
    create index ix_node_path on TREE(NodePath)

    pak všechny uzly pod daným uzlem:
    select * from TREE where NodePath LIKE ‚xxxxx%‘

    Omezení – hloubka stromu, počet položek, storage
    Výhody – performance boost, jak čtení tak zápis je rychlý (žádný traversal), jednoduché hromadné operace

    MS SQL 2008 R2+ umí T-TREE indexy, umí opravdu překvapivě rychle i
    select * from TREE where NodePath LIKE ‚%xxxxxyyyyy%‘
    tedy operace se subtrees

Napsat komentář

Přihlásit se

Tato diskuse je již příliš stará, pravděpodobně již vám nikdo neodpoví. Pokud se chcete na něco zeptat, použijte diskusní server Devel.cz

Zdroj: http://www.zdrojak.cz/?p=3616