Práctica recomendada para mantener los datos en la memoria y la base de datos al mismo tiempo en Android

Estamos diseñando una aplicación para Android que tiene muchos datos ("clientes", "productos", "pedidos" …) y no queremos consultar SQLite cada vez que necesitamos algún registro. Queremos evitar consultar la base de datos lo más que podamos, por lo que decidimos mantener ciertos datos siempre en la memoria.

Nuestra idea inicial es crear dos clases simples:

  1. "MemoryRecord": una clase que contendrá básicamente una matriz de objetos (string, int, double, datetime, etc …), que son los datos de un registro de tabla, y todos los métodos para obtener esos datos dentro o fuera de este formación.

  2. "MemoryTable": una clase que contendrá básicamente un Mapa de [Key, MemoryRecord] y todos los métodos para manipular este Mapa e insertar / actualizar / borrar registro en / desde la base de datos.

Esas clases se derivarán de cada tipo de tabla que tenemos en la base de datos. Por supuesto hay otros métodos útiles no enumerados arriba, pero no son importantes en este punto.

Por lo tanto, al iniciar la aplicación, vamos a cargar las tablas de una base de datos SQLite a la memoria con esas clases, y cada vez que tenemos que cambiar algunos datos, vamos a cambiar en la memoria y publicar en la base de datos justo después.

Pero, queremos alguna ayuda / consejo de usted. ¿Puede sugerir algo más simple o eficiente para implementar tal cosa? O tal vez algunas clases existentes que ya lo hacen por nosotros?

Entiendo lo que ustedes están tratando de mostrarme, y les doy las gracias por eso.

Pero, digamos que tenemos una tabla con 2000 registros, y necesitaré listar esos registros. Para cada uno, tengo que consultar otras 30 tablas (algunas con 1000 registros, otras con 10 registros) para agregar información adicional en la lista, y esto mientras que es "volar" (y como usted sabe, debemos ser muy rápido en este momento).

Ahora usted va a decir: "Basta con construir su consulta principal con todas esas" juntas ", y traer todo lo que necesita en un paso. SQLite puede ser muy rápido, si su base de datos está bien diseñado, etc …".

Aceptar, pero esta consulta se volverá muy complicada y segura, aunque SQLite es muy rápido, será "demasiado" lento (2 a 4 segundos, como he confirmado, y esto no es un tiempo aceptable para nosotros).

Otro complicador es que, dependiendo de la interacción del usuario, necesitamos "volver a consultar" todos los registros, porque las tablas involucradas no son las mismas, y tenemos que "volver a unirse" con otro conjunto de tablas.

Por lo tanto, una alternativa es traer sólo los registros principales (esto nunca cambiará, no importa lo que el usuario hace o quiere) sin join (esto es muy rápido!) Y consulta las otras tablas cada vez que queremos algunos datos. Tenga en cuenta que en la tabla con 10 registros sólo, vamos a buscar los mismos registros muchas y muchas veces. En este caso, es una pérdida de tiempo, porque SQLite SQLite es rápido, siempre será más caro para la consulta, el cursor, buscar, etc … que sólo agarrar el registro de una especie de "caché de memoria". Quiero dejar claro que no planeamos mantener todos los datos en la memoria siempre, solo algunas tablas que consultamos muy a menudo.

Y llegamos a la pregunta original: ¿Cuál es la mejor manera de "almacenar" esos registros? Realmente me gusta enfocar la discusión en eso y no "¿por qué necesita almacenar datos en caché?"

La gran mayoría de las aplicaciones de la plataforma (contactos, correo electrónico, Gmail, calendario, etc.) no lo hacen. Algunos de ellos tienen esquemas de base de datos extremadamente complicados con potencialmente una gran cantidad de datos y no es necesario hacerlo. Lo que usted está proponiendo hacer va a causar un dolor enorme para usted, sin ganancia clara.

Primero debe centrarse en diseñar su base de datos y esquema para poder realizar consultas eficientes. Hay dos razones principales por las que puedo pensar para que el acceso a la base de datos sea lento:

  • Tienes esquemas de datos muy complicados.
  • Tienes una gran cantidad de datos.

Si usted va a tener una gran cantidad de datos, no puede permitirse el lujo de mantener todo en la memoria de todos modos, por lo que este es un callejón sin salida. Si tienes estructuras complicadas, te beneficiarías en ambos casos al optimizarlas para mejorar el rendimiento. En ambos casos, el esquema de base de datos va a ser clave para un buen rendimiento.

En realidad, la optimización del esquema puede ser un poco un arte negro (y yo no soy un experto en ello), pero algunas cosas a buscar son correctamente la creación de índices en las filas que consulta, el diseño de las uniones para que tomen caminos eficientes, etc Estoy seguro de que hay mucha gente que puede ayudarte en esta área.

También puede tratar de buscar en la fuente de algunas de las bases de datos de la plataforma para obtener algunas ideas de cómo diseñar para un buen rendimiento. Por ejemplo, la base de datos Contactos (especialmente a partir de 2.0) es extremadamente complicada y tiene muchas optimizaciones para proporcionar un buen rendimiento en datos relativamente grandes y conjuntos de datos extensibles con muchos tipos diferentes de consultas.

Actualizar:

He aquí un buen ejemplo de lo importante que es la optimización de bases de datos. En la base de datos de proveedores de medios de Android, una versión más reciente de la plataforma cambió el esquema significativamente para agregar algunas nuevas características. El código de actualización para modificar una base de datos de medios existente en el nuevo esquema puede tardar 8 minutos o más en ejecutarse.

Un ingeniero realizó una optimización que redujo el tiempo de actualización de una base de datos de prueba real de 8 minutos a 8 segundos. Una mejora de rendimiento de 60x.

¿Qué fue esta optimización?

Era crear un índice temporal, en el punto de la mejora, en una columna importante usada en las operaciones de la mejora. (Y, a continuación, eliminarlo cuando haya terminado.) Por lo que esta mejora del rendimiento 60x viene, aunque también incluye el tiempo necesario para construir un índice en una de las columnas utilizadas durante la actualización.

SQLite es una de esas cosas donde si sabes lo que estás haciendo puede ser notablemente eficiente. Y si usted no toma cuidado en cómo usted lo utiliza, usted puede terminar para arriba con funcionamiento miserable. Es una apuesta segura, sin embargo, si usted está teniendo problemas de rendimiento con él que se pueden arreglar mediante la mejora de cómo está utilizando SQLite.

El problema con un caché de memoria es, por supuesto, que usted necesita para mantener en sincronía con la base de datos. He encontrado que la consulta de la base de datos es realmente bastante rápido, y es posible que pre-optimización aquí. He hecho un montón de pruebas en las consultas con diferentes conjuntos de datos y nunca toman más de 10-20 ms.

Todo depende de cómo esté utilizando los datos, por supuesto. ListViews están bastante bien optimizados para manejar un gran número de filas (he probado en la gama 5000 sin problemas reales).

Si se va a quedar con la caché de memoria, es posible que desee que la base de datos de notificar la caché cuando su contenido cambia y, a continuación, puede actualizar la caché. De esta manera cualquiera puede actualizar la base de datos sin saber sobre el almacenamiento en caché. Además, si crea un ContentProvider sobre su base de datos, puede utilizar ContentResolver para notificarle los cambios si se registra con registerContentObserver.

  • Mejores Prácticas de Android - Comunicación entre Actividad y Fragmentos
  • Cómo lograr animaciones de transacciones de fragmentos suaves en Android
  • Velocidad de inicio en startActivity
  • Android personalizado listview muy lento al desplazarse
  • ¿Cómo afecta la profundidad de color y / o el nivel de compresión de las imágenes al rendimiento de la interfaz de usuario?
  • La aplicación o la actividad lleva tiempo para cargarse algunas veces
  • Problema "La prueba del repositorio tiene un error" al intentar importar el proyecto de bitbucket al android studio
  • Tiempo inactivo de actividad para ActivityRecord
  • Cuenta de simulacro en ActivityInstrumentationTestCase2
  • Consejos para mejorar la tasa de llenado de OpenGL ES en Android
  • Uso de la batería, ¿qué esperar?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.