Android: ContentProvider para cada tabla / manejo de relaciones uno-a-muchos

Cuando se utiliza un proveedor de contenido para el acceso a la base de datos SQLite

  1. ¿Es una mejor práctica tener un proveedor de contenido para cada tabla o usar uno para todas las tablas?
  2. ¿Cómo manejar relaciones uno-a-muchos al crear nuevos registros?

Un ContentProvider no es una base de datos

Un ContentProvider es una forma de acceder públicamente (o semi-públicamente) a los datos como contenido. Esto puede hacerse de varias maneras, a través de acceso a archivos, SQLite o incluso acceso a la web. Un ContentProvider en sí mismo no es una base de datos, pero puede programar una base de datos para ello. También puede tener varios ContentProviders accediendo a la misma base de datos, pero distribuyendo diferentes niveles de acceso, o el mismo contenido de diferentes maneras según el solicitante.

Lo que realmente estás pidiendo no es una pregunta de ContentProvider, sino una pregunta de la base de datos "Cómo manejar las relaciones en una base de datos SQLite" porque el ContentProvider no utiliza ningún código de base de datos a menos que lo digas a través de SQLiteOpenHelper y otras clases similares. Por lo tanto, simplemente tiene que programar su acceso a la base de datos correctamente y su base de datos SQLite funcionará como desee.

Una base de datos es una base de datos

En los viejos tiempos, las bases de datos eran simplemente archivos planos donde cada tabla era a menudo su propia entidad para permitir el crecimiento. Ahora, con DBMS, hay muy poca razón para hacerlo. SQLite es como cualquier otra plataforma de base de datos en este sentido y puede albergar tantas mesas como tenga espacio para contenerlas.

SQLite

Hay ciertas características que SQLite maneja bien, algunas que maneja – pero no bien, y algunas que no maneja en absoluto. Las relaciones son una de esas cosas que quedaron fuera de algunas versiones de SQLite de Android, porque se envió sin soporte de clave extranjera. Esta fue una característica muy solicitada y se añadió en SQLite 3.6.22 que no se envió hasta Android 2.2. Todavía hay muchos errores reportados con él, sin embargo, en sus primeras encarnaciones.

Android pre 2.2

Afortunadamente, ser compatible con SQL y un simple DBMS (no RDBMS en este momento), hay algunas maneras fáciles de evitar esto, después de todo, una clave extranjera es sólo un campo en otra tabla.

  1. Puede aplicar las INSERT y UPDATE base de datos creando CONSTRAINT s cuando utilice su CREATE TABLE .
  2. Puede consultar la otra tabla para el _id adecuado para obtener su clave externa.
  3. Puede consultar su tabla de origen con cualquier instrucción SELECT apropiada utilizando un INNER JOIN , lo que impone una pseudo-relación.

Dado que la versión de Android de SQLite no hace cumplir las relaciones directamente, si quería CASCADE ON DELETE tendría que hacerlo manualmente. Pero esto puede hacerse a través de otra instrucción SQL simple. He escrito esencialmente mi propia biblioteca para hacer cumplir este tipo de relaciones, ya que todo debe hacerse manualmente. Debo decir, sin embargo, la eficiencia de SQLite y SQL como un todo lo hace muy rápido y fácil.

En esencia, el proceso para cualquier relación forzada es el siguiente:

  • En una consulta que requiere una clave externa, utilice un JOIN .
  • En un INSERT utilizar un CONSTRAINT en el campo de clave externa de NOT NULL
  • En una UPDATE en el campo de clave principal que es una clave externa en otro TABLE , ejecute una segunda UPDATE en el TABLE relacionado que tiene la clave externa. (CASCADE UPDATE)
  • Para un DELETE con los mismos parámetros, haga otro DELETE con el where siendo foreign_key = _id (asegúrese de obtener el _id antes de _id la fila, en primer lugar).

Android 2.2+

Las claves externas están soportadas, pero están desactivadas de forma predeterminada. Primero tienes que encenderlos:

 db.execSQL("PRAGMA foreign_keys=ON;"); 

A continuación tienes que crear la relación TRIGGER . Esto se hace cuando se crea la TABLE , en lugar de una instrucción separada TRIGGER . Vea abajo:

 // Added at the end of CREATE TABLE statement in the MANY table FOREIGN KEY(foreign_key_name) REFERENCES one_table_name(primary_key_name) 

Para obtener más información sobre SQLite y sus capacidades, consulte el sitio oficial de SQLite . Esto es importante ya que no tiene todos los JOIN s que realiza en otros RDBMS. Para obtener información específica sobre las clases SQLite en Android, lea la documentación .

En cuanto a la primera pregunta: no es necesario crear proveedor de contenido para cada tabla. Puede utilizar en con varias tablas, pero la complejidad del proveedor aumentó con cada tabla.

Un proveedor de contenido es aproximadamente equivalente al concepto de una base de datos. Tendría varias tablas en una base de datos, por lo que tener varias tablas en su proveedor de contenido tiene sentido.

Una a muchas relaciones pueden ser manejadas como en cualquier otra base de datos. Utilice referencias y claves foráneas como lo haría con cualquier otra base de datos. Puede utilizar cosas como CASCADE ON DELETE para asegurarse de que los registros se borran cuando los registros que hacen referencia en otras tablas también se eliminan.

  • ¿Qué pasa si devuelve false en OnCreate de ContentProvider?
  • Proveedor de contenido INSTALL_FAILED_CONFLICTING_PROVIDER (instalación del proveedor de contenido como un apk independiente)
  • Consulta de base de datos de Android ContentProvider varias tablas
  • Prácticas recomendadas para unir tablas y notificar a ContentObservers en Android ContentProvider
  • Página web del navegador web de Android
  • Android - Seleccionar máximo en contentProvider
  • ¿Por qué esta variable se establece en cadena vacía cuando ya se inicializa a una cadena vacía?
  • Proveedor de contenido de Android y Gradle productFlavours
  • Cómo probar proveedores de contenido en Android
  • NotifyChange con uri modificado de contentProvider.update ()
  • ¿Es posible falsificar un SMS entrante en Android?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.