Stiamo progettando un'app per Android che ha molti dati ("clienti", "prodotti", "ordini" ...) e noi doniamo 'Voglio interrogare SQLite ogni volta che abbiamo bisogno di un record. Vogliamo evitare di interrogare il database il più possibile, quindi abbiamo deciso di mantenere certi dati sempre in memoria.Best practice per mantenere i dati in memoria e database contemporaneamente su Android
La nostra idea iniziale è quella di creare due classi semplici:
"MemoryRecord": una classe che conterrà essenzialmente un array di oggetti (string, int, double, datetime, ecc ...), che sono i dati di un record di tabella e tutti i metodi per ottenere quei dati in/out da questo array.
"MemoryTable": una classe che conterrà essenzialmente una mappa di [Key, MemoryRecord] e tutti i metodi per manipolare questa mappa e inserire/aggiornare/eliminare record in/dal database.
Tali classi saranno derivate da ogni tipo di tabella presente nel database. Naturalmente ci sono altri metodi utili non elencati sopra, ma a questo punto non sono importanti.
Quindi, quando avvieremo l'applicazione, caricheremo tali tabelle da un database SQLite alla memoria usando quelle classi, e ogni volta che dovremo modificare alcuni dati, cambieremo in memoria e li inseriremo nel database subito dopo.
Ma, vogliamo qualche aiuto/consiglio da parte vostra. Puoi suggerire qualcosa di più semplice o efficace per implementare una cosa del genere? O forse alcune classi esistenti che già lo fanno per noi?
Capisco quello che voi ragazzi state cercando di mostrarmi, e vi ringrazio per questo.
Ma supponiamo di avere una tabella con 2000 record e sarà necessario elencarli. Per ognuno, devo interrogare altre 30 tabelle (alcune con 1000 record, altre con 10 record) per aggiungere ulteriori informazioni nella lista, e questo mentre è "volante" (e come sapete, dobbiamo essere molto veloci in questo momento).
Ora dirai: "costruisci la tua query principale con tutti questi" join "e porta tutto ciò che ti serve in un unico passaggio: SQLite può essere molto veloce, se il tuo database è ben progettato, ecc. .. ".
OK, ma questa query diventerà molto complicata e sicura, anche se SQLite è molto veloce, sarà "troppo" lento (2 a 4 secondi, come ho confermato, e questo non è un tempo accettabile per noi).
Un altro complicatore è che, in base all'interazione dell'utente, è necessario "interrogare nuovamente" tutti i record, perché le tabelle coinvolte non sono le stesse e dobbiamo "re-join" con un altro insieme di tabelle.
Quindi, un'alternativa è portare solo i record principali (questo non cambierà mai, non importa cosa l'utente fa o vuole) senza alcun join (questo è molto veloce!) E interrogare le altre tabelle ogni volta che vogliamo alcuni dati. Nota che sul tavolo con solo 10 record, recupereremo gli stessi record molte e molte volte. In questo caso, è uno spreco di tempo, perché non importa quale sia lo SQLite veloce, sarà sempre più costoso interrogare, spostare il cursore, recuperare, ecc. Piuttosto che prendere il record da una sorta di "cache di memoria". Voglio chiarire che non abbiamo in programma di mantenere sempre tutti i dati in memoria, solo alcune tabelle vengono interrogate molto spesso.
E siamo arrivati alla domanda iniziale: qual è il modo migliore per "memorizzare" quei record? Mi piace molto concentrare la discussione su questo e non "perché è necessario memorizzare i dati nella cache?"
"Vogliamo evitare di interrogare il database il più possibile, quindi abbiamo deciso di mantenere alcuni dati sempre nella memoria." - hai utilizzato Traceview per confermare che si tratta di un problema per la tua app? "Vogliamo qualche aiuto/consiglio da parte tua" - il mio consiglio è: provare prima c'è un problema. Hai pochissima RAM con cui lavorare. Costruire qualche quadro importante per affrontare un problema inesistente sarebbe uno spreco di energie. Se hai dimostrato che questo è un problema, mi piacerebbe un puntatore al post del blog in cui l'hai scritto, dato che sono sempre interessato ai risultati dei test delle prestazioni. – CommonsWare
@CommonsWare: Capisco il tuo punto e sono completamente d'accordo con te. Ma, come sviluppatori PalmOS e .NetCF, abbiamo già affrontato questo problema prima. In PalmOS tutti i dati sono in memoria in base alla progettazione (.pdb) e non si verificano problemi di prestazioni durante l'acquisizione dei dati. Nell'altra mano, in WM affrontiamo "il problema", e quindi abbiamo creato questa "soluzione" sopra elencata. Ma ora, in Android, desideriamo fare "nel modo giusto". Vogliamo sapere se stiamo per affrontare problemi di prestazioni quando si interrompe il database "ogni volta". Quindi abbiamo deciso di chiedere suggerimenti qui. Grazie comunque. – Christian
"Vogliamo sapere se stiamo per affrontare problemi di prestazioni quando interrompiamo il database" ogni volta ", così abbiamo deciso di chiedere dei suggerimenti qui." -- No, tu non l'hai fatto. Vorrei che tu avessi. Invece, hai dichiarato che esisteva un problema ("non vogliamo interrogare sqlite ogni volta che abbiamo bisogno di qualche record") e volevi aiuto con la tua soluzione. Come con la maggior parte delle piattaforme, la risposta a se si "affronteranno problemi di prestazioni quando si interrompe il database" è "dipende dalle query". Fidati di me, solo perché c'è un problema su WM non significa che lo stesso problema esiste altrove. Usa Traceview. – CommonsWare