2012-03-26 11 views
7

Sto lavorando per sviluppare un'applicazione che deve interrogare a un certo momento, un database con oltre 4k righe e ogni riga ha 90 campi (Stringhe). Il problema è che se seleziono * dal database, il mio cursore diventa veramente grande (oltre 4 MB). E il cursore in Android è limitato a 1 MB. Come posso risolvere questo, o qual è il metodo più elegante per risolvere il problema? È possibile dividere il database in blocchi più piccoli e interrogarli?Android come interrogare un enorme database in Android (la dimensione del cursore è limitata a 1MB)

Grazie, Arkde

risposta

7

Ho trovato un modo per gestire questo e voglio condividere con tutti coloro che ne hanno bisogno.

int limit = 0; 
    while (limit + 100 < numberOfRows) { 
     //Compose the statement 
     String statement = "SELECT * FROM Table ORDER someField LIMIT '"+ limit+"', 100"; 
     //Execute the query 
     Cursor cursor = myDataBase.rawQuery(statement, null); 
     while (cursor.moveToNext()) { 
      Product product = new Product(); 
      product.setAllValuesFromCursor(cursor); 
      productsArrayList.add(product); 
     } 
     cursor.close(); 
     limit += 100; 
} 

//Compose the statement 
String statement = "SELECT * FROM Table ORDER someField LIMIT '"+ (numberOfRows - limit)+"', 100"; 
//Execute the query 
Cursor cursor = myDataBase.rawQuery(statement, null); 

while (cursor.moveToNext()) { 
    Product product = new Product(); 
    product.setAllValuesFromCursor(cursor); 
    productsArrayList.add(product); 
} 
cursor.close(); 

L'idea principale è quella di dividere i dati, in modo da poter utilizzare il cursore come dovrebbe essere utilizzato. Funziona sotto 2 s per 5k righe se hai una tabella indicizzata.

Grazie, Arkde

1

Avete bisogno di tutte queste righe allo stesso tempo? Puoi prenderli in alcune parti? Questa domanda è stata posta più volte: Android SQLite and huge data sets

Ecco un altro suggerimento: se hai 90 campi che devi modificare, dividerli in 10 diverse viste. In ogni vista, una freccia sinistra e una freccia destra consentono di attraversare orizzontalmente gli schermi. Quindi ogni vista mostrerà 9 campi. O qualche strategia del genere. Essenzialmente queste sono tutte le stesse viste tranne i nomi delle colonne quindi non dovresti dover modificare molto codice.

+0

Sì, ho bisogno di tutti questi file allo stesso tempo, da quando ho bisogno di loro memorizzati in un ArrayList per riempire e adattatore per un controllo ListView. E i problemi sembrano essere con la dimensione degli oggetti memorizzati nel cursore non con il numero di righe (nella domanda risposta nel link suggerito, c'è un problema con il numero di righe) – Arkde

+0

Il limite si applica ai dati globali, sia è dovuto a un numero elevato di righe o colonne molto grandi o molte colonne. Non conosco alcuna alternativa, ma per compattare i dati in qualche modo. – Sid

+0

Qualche idea su come posso compattare i miei dati? Ho usato String per memorizzarli, dal momento che la dimensione della stringa cresce con il numero di caratteri al suo interno ...Non conosco altro modo per ottimizzare questo. – Arkde

0

Come regola, non selezionare mai *. Per iniziare ogni riga avrà un identificatore univoco e il tuo utente vorrà selezionare solo determinate righe e colonne, cioè quello che possono vedere su uno schermo Android. Senza sembrare essere maleducato questa è una domanda piuttosto elementare. Si restituiscono solo le colonne e le righe che si desidera visualizzare per quella schermata sul telefono, altrimenti si consuma una durata inutile della batteria che non trasmette mai dati diaplayer. l'approccio standard consiste nell'usare procedure memorizzate parametrizzate. Google ha parametrizzato le stored procedure e fa un po 'di lettura - non aggiornando le unlees di tabella restituite l'identificatore di riga univoco per quella tabella.

+0

Devo fare una selezione * perché, purtroppo, ho bisogno di tutti i campi da utilizzare. L'utente modificherà alcuni campi e altri verranno utilizzati per impostazioni diverse. – Arkde

+0

In tal caso, avrei SQL dinamico in cui i nomi dei campi vengono generati dall'utente che li seleziona da un elenco di caselle di controllo, più eventuali campi nascosti che è necessario aggiornare, quindi passare a una vista di dettaglio. Puoi anche fare una dichiarazione di aggiornamento dinamico. Non so ancora come si ottengono tutti quei dati su un tipico display Android. –

2

Ian P ha perfettamente ragione. Per espandere la sua risposta, se hai 90 campi probabilmente non stai usando le strategie più efficienti. È necessario disporre di più tabelle, che si collegano per ID. Non dovresti MAI semplicemente racchiudere ogni singola variabile che potresti avere o meno in una tabella. È per questo che stai superando le dimensioni. Anche se stavi copiando un enorme foglio di calcolo Excel con 90 colonne, dovresti progettare di recuperarne solo alcune alla volta. Un utente mobile NON attenderà assolutamente quella query. Non lo faranno. @ 3G accelera la richiesta di un sacco da parte dei tuoi potenziali utenti. Non solo stai chiedendo loro di sedersi e aspettare mentre vedono letteralmente che non succede nulla per ~ 5 minuti, inoltre stai anche richiedendo una durata della batteria preziosa.

1 MB è generoso. Se recuperi i dati secondo necessità e utilizzi strategie di codifica efficienti, 1 MB sarà più di quanto avrai mai bisogno.

Problemi correlati