Rekurzivní výkon zpracování dat pomocí Java a SQLite

hlasů
4

Máte-li odpověď, která není Java / SQLite souvisí, byl bych potěšen, aby si ho přečetli.

Prostředí

I ukládat položky v databázi následujícího schématu:

###################
#       Item      #    
###################
#      _id        #    This is the primary key
#    parent_id    #    If set, it the ID of the item containing this item
#      date       #    An ordinary date
#  geocontext_id  #    Foreign key to a pair of named coordinates
###################

###################
#   Geocontext    #    
###################
#       _id       #    This is the primary key
#       name      #    Way for the user to label a pair of coordinates (e.g : home, work)
#         x       #    One of the coordinate
#         y       #    The other one
###################

Problém

Musím filtrovat položky podle geocontext a datum. Jednalo by se o snadný úkol, pokud položky byli všichni na stejné úrovni, ale trik je to rekurzivní. EG:

root
      |_item 1
      |_item 2 
      |      |_item 4
      |      |_item 5
      |             |_item 6
      |_item 3
      |      |_item 8
      |             |_item 10
      |_item 11
      |       |_item 12
      |_item 7

Neexistuje žádný explicitní limit pro rekurzivní hloubku.

Teď, když jsme v každém uzlu a filtrem s datem „1. dubna“, musíme vidět nejen položky přímo obsažených v uzlu, který odpovídal datum, ale musíme vidět položky, které obsahují položky odpovídající datum, jakož ,

EG: Jsme v „bodech 2“, pokud „bod 6“ odpovídá datum, pak považujeme za „bod 5“ odpovídá datum a taky musíme ho udržet. Jsme-li u kořene, pak musí být zobrazena položka 2.

Totéž platí i pro geocontext, ale je to ještě těžší, protože:

  • Je uložena v druhé tabulce.
  • Odpovídající kontext je nákladný matematický výpočet.

Samozřejmě, brutální nutit shodu by mělo za následek software být pomalé a velmi špatné uživatelské zkušenosti.

Poznámka: Nepotřebuji k zobrazení stromu . Zobrazení I seznamu filtrovaných dat ze stromu. Musíme vidět jen plochý seznam nejlepších prvků. Hlavním úkolem je rozhodnout, zda se má zobrazit jednotlivé prvky nebo ne, podle všeho děti hierarchii.

Jak jsem se snažil vyřešit

Myslel jsem, že bych mohl zmírnit trochu problém pomocí více tabulek do mezipaměti ploché údaje:

###################
# Geocontex_cache #    
###################
#     item_id     #     I can Join the items table on this field
#     child_id    #     I can delete / update a child, and so delete / update the cache
#  geocontext_id  #     I can delete / update a geocontext, and so delete / update the cache
#        x        #      Here, I can brute force :-)
#        y        # 
###################

###################
#    Date_cache   #    
###################
#     item_id     #     
#     child_id    #    
#       date      #    
###################

To se zdá být rozumné, ale ještě jsem to zkusil. Nicméně, to by mělo tyto nevýhody:

  • Přestěhovala jsem se nákladný proces s get / set / Vytvořit / odstranit způsoby, které budou muset řídit mezipaměti data. To bude nepříjemné kód psát a udržovat. Položka úroveň pět hloubka bude triger proces, který zasáhne rekurzivně pět rodiče.

  • Velikost ot datová základna by se mohla stát obrovský. Pěti de hloubka hladiny store položka mezipaměti dat po dobu pěti rodičů. Nevím, jestli je to důležité, protože tento aa mono-uživatelské aplikace s ručním vstupem. Nemyslím si, že by někdo vložit více thatn 1000 položek s více než 10 úrovní hloubky.

Nyní je dobrou zprávou je, že jsme jít ze dna pyramidy na vrchol, ne jiným způsobem, takže to není má hrozný, jak se zdá. Když jsem se bude muset vypořádat s delecí rodič položky, bude to další pěkné hlavy, ale já si to na další otázku ;-).

Teď moje otázka

Jak byste ukládat data a zpracovat filtrování int nejoptimálnějším způsobem?

Volitelné:

Měl jsem definovat explicitní rekurzivní limitu hloubky? Měl bych provést filtrování pomocí SQL nebo Java? SQL jistě bude rychlejší, ale odpovídající geocontext je mnohem snazší udělat v Javě.

Jak jsem pracoval na platformě Android, mám následující omezení:

  • Java je jediný jazyk k dispozici, a to s celým standardním lib.

  • SQLite je jediný DBMS k dispozici.

  • Výkon a paměť jsou důležité otázky. V případě, že máte na výběr, životnost baterie a tudíž výkon je prioritou.

  • Exotika externí libs nemusí být schopen využít.

PS: kopal jsem do SO a zjistil některé zajímavé kousky informací (espacially Jaký je nejúčinnější / elegantní způsob, jak analyzovat plochý stůl do stromu? ). Je to náznak, ale ne řešit problémy.

Položena 04/04/2009 v 11:18
zdroj uživatelem
V jiných jazycích...                            


4 odpovědí

hlasů
5

1) Za prvé, pojďme se podívat na jednoduše uvedení vše v paměti. To je jednoduché, flexibilní a především rychle, řešení. Nevýhody patří skutečnost, že budete muset přečíst všechno, co do paměti při startu (dát uživateli pěkný ukazatel průběhu načítání a nebudou ani nevšiml), a možná muset udělat trochu práce navíc, aby vše se odráží na disk, když uživatel si myslí, že je to tak, že data nejsou ztraceny.

V této analýze budu dělat nějaké obecné předpoklady o Android / Dalvik Já opravdu nevím, že hodně o, takže doufejme, že to je poněkud přesný :) Nezapomeňte, G1 má 192 MB RAM. Také váš předpoklad výše byla max kolem 1000 kusů.

Object superclass ~ 8 bytes
parent/child pointer ~ 4 bytes
date (long) ~ 8 bytes
name (non interned string avg 32 chars) ~ 64 bytes
x point (int) ~ 4 bytes
y point (int) ~ 4 bytes

Total = 92 bytes + possible memory alignment + fudge factor = 128 bytes
1000 items = 125kB
10000 items = 1.22MB

Poznámka: Uvědomuji si, že když se dítě může mít pouze jeden ukazatel, rodič může mít více dětí. Nicméně, počet mateřských> dětských ukazatelů je (prvky - 1), takže průměrné náklady na mateřských> dětské ukazatel je (prvky - 1) / prvky ~ 1 prvek 4 bajty. To předpokládá, že podřízené struktury, která nemá přidělit nevyužité paměti, jako je například lineární seznam (na rozdíl od ArrayList)

2) blbeček ve mně říká, že by to bylo zábavné místo na profil B + strom, ale myslím, že je to zbytečná pro to, co chcete v tuto chvíli :) Nicméně, bez ohledu na řešení, které skončit přijetím, pokud nejste držet vše paměť, budete určitě chtít, aby mezipaměti co nejvíce z nejlepších úrovní stromu v paměti, jak jen můžete. To může snížit o výši diskovou aktivitu drasticky.

3) Pokud nechcete jít celou paměť, dalším možným řešením by mohlo být takto. Bill Karwin naznačuje spíše elegantní RDBMS struktury zvané Uzavření stolu pro optimalizaci stromu založeného čte, zároveň složitější zápisy. V kombinaci s vyrovnávací nejvyšší úrovně vám může dát výhody výkonu, i když bych tento test před nástupem své slovo na to:

Při vyhodnocování pohled, použijte cokoliv máte v paměti vyhodnotit tolik dětí, kolik jen můžete. Pro ty děti, které se neshodují, použijte SQL spojení mezi tabulkou uzávěru a rovný stůl s vhodným kde klauzule zjistit, jestli existují nějaké odpovídající děti. Pokud ano, budete zobrazovat, že uzel v seznamu výsledků.

Doufám, že to všechno dává smysl, a vypadá, že bude pracovat pro to, co potřebujete.

Odpovězeno 07/04/2009 v 16:56
zdroj uživatelem

hlasů
2

Poslouchal jsem Soonil a dal příležitost k «uzavření stolu». Přidal jsem v následující tabulce:

################
#   Closure    #
################
# ancestor_id  #
#   item_id    #
################

Pokud se stejně jako já jste nikdy nepoužíval tohoto modelu před, funguje to takhle:

Přidat řádek pro každý přímý nebo nepřímý vztah v hierarchii. Pokud C je podřízený B a B o dítě, máte:

ancestor    item
   B         C
   A         B
   A         C      # you add the indirect relationship   
   A         A
   B         B
   C         C      # don't forget any item is in relation with himself 

Nicméně, s tímto schématem, že vám něco chybí důležité informace: jaké jsou přímé vztahy? Co když chcete jen přímí synové položky?

Za to, že můžete přidat sloupec is_directs bool v tabulce uzávěru, nebo můžete jen držet sloupec parent_idv itemtabulce. Že to, co jsem udělal, protože mi brání přepisování spoustu mého předchozího kódu.

Pěkné na tom je, že nyní mohu zkontrolovat, zda je položka odpovídá datum nebo geocontext v jednom dotazu.

EG, když jsem procházení všechny položky obsažené v poř 4 a chtějí získat jen ty odpovídající nebo obsahující dětem odpovídající datum D:

SELECT ti.parent_id, ti.id, ti.title 
FROM item AS di                                  # item to filter with the date
              JOIN closure AS c                  # closure table
                  ON (di.id = c.item_id) 
              JOIN item AS ti 
                  ON (c.ancestor_id = ti.id)     # top item to display
WHERE di.date = D                                # here you filter by date   
AND ti.parent_id = 4                             # here you ensure you got only the top items

Takže můžu vyhodit všechny své *_cachetabulky. Stále mám hodně práce dělat jeden UPDATE / DELETE / CREATE , ale vše je centralizovaný a většina z toho je procesní, není rekurzivní. Dost dobrý.

Jedinou bolestí je, že musím rekurzivně přidat položku ke všem jeho předchůdce. Ale dostat předky je jeden dotaz záběr, takže je to opravdu rozumné. A samozřejmě tabulka uzávěr trvat hodně prostoru, ale v mém případě jsem se prostě nezajímá. Nezapomeňte indexu, pokud hledáte perfs ...

Milovat tento SQL trik, díky moc kluci! Je to trochu složitější se dostat na první pohled, ale stejně tak zřejmé, jakmile jste to udělal.

Odpovězeno 17/04/2009 v 16:58
zdroj uživatelem

hlasů
1

To by mohlo být offtopic ale .. jste považován za použití serializace?

Google Protocol Nárazníky by mohly být použity k serializaci dat ve velmi účinným způsobem (čas a prostor), měli byste si vytvořit vhodnou stromovou strukturu (vypadat v každém CS knize), aby pomohl s hledáním.

Zmínil jsem protokolů vyrovnávacích pamětí, protože je knihovna Google mohou být k dispozici na Android.

Jen myšlenka.

Odpovězeno 04/04/2009 v 11:28
zdroj uživatelem

hlasů
-1

AFAICT můžete použít hierarchické dotazy (google pro „připojit“ „START WITH“) v SQLite ...

Odpovězeno 04/04/2009 v 17:35
zdroj uživatelem

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more