2011-09-21 11 views
10

Quando si utilizza un provider di contenuti per l'accesso al database SQLiteAndroid: ContentProvider per ogni tabella/movimentazione uno-a-molti

  1. è meglio la pratica di avere un fornitore di contenuti per ogni tabella o per utilizzare uno per tutti tavoli?
  2. Come gestire le relazioni uno-a-molti durante la creazione di nuovi record?
+0

Puoi fornire un po 'più di dettaglio su cosa intendi con "Come gestire le relazioni one to man" stai parlando di progettazione di database SQL, CREATE Statements o ti stai chiedendo come farlo dal lato Content Provider. – AGrunewald

risposta

15

Un ContentProvider non è un database

Un ContentProvider è un modo per pubblico (o semi-pubblicamente) dati di accesso come contenuto. Questo può essere fatto in diversi modi, tramite accesso ai file, SQLite o persino accesso web. Un ContentProvider in sé e per sé non è un database, ma è possibile programmarne un database. Potresti anche avere più ContentProvider che accedono allo stesso database, ma che distribuiscono diversi livelli di accesso o lo stesso contenuto in modi diversi a seconda del richiedente.

Ciò che si sta chiedendo non è una domanda di ContentProvider, ma una domanda di database "Come gestire le relazioni in un database SQLite" perché ContentProvider non utilizza alcun codice di database a meno che non lo comunichi tramite uno SQLiteOpenHelper e altri simili classi. Quindi, è sufficiente programmare correttamente l'accesso al database e il database SQLite funzionerà come desiderato.

Un database è un database

Ai vecchi tempi, i database sono stati i file semplicemente piatte dove ogni tavolo era spesso la sua propria entità per consentire la crescita. Ora, con DBMS, c'è ben poca ragione per farlo. SQLite è proprio come qualsiasi altra piattaforma di database in questo senso e può ospitare tante tabelle quante ne hai per tenerle.

SQLite

ci sono alcune caratteristiche che SQLite gestisce bene, alcuni che gestisce - ma non bene, e alcuni che non gestisce affatto. Le relazioni sono una di quelle cose che sono state lasciate fuori da alcune versioni di SQLite di Android, perché spedite senza supporto di chiavi esterne. Questa era una funzionalità molto richiesta ed è stata aggiunta in SQLite 3.6.22 che non è stata spedita fino ad Android 2.2. Ci sono ancora molti bug segnalati, tuttavia, nelle sue prime incarnazioni.

Android pre 2.2

fortuna di essere SQL compliant e un semplice DBMS (non RDBMS in questo momento), ci sono alcuni semplici modi per aggirare questo, dopo tutto, una chiave esterna è solo un campo in un altro tavolo

  1. È possibile applicare del database INSERT e UPDATE dichiarazioni creando CONSTRAINT s quando si utilizza la sua dichiarazione CREATE TABLE.
  2. È possibile interrogare l'altra tabella per l'appropriato _id per ottenere la chiave esterna.
  3. È possibile interrogare la tabella di origine con qualsiasi istruzione SELECT appropriata utilizzando uno INNER JOIN, applicando così una pseudo-relazione.

Poiché la versione di SQLite di Android non applica direttamente le relazioni, se si desidera eseguire CASCADE ON DELETE, è necessario eseguirlo manualmente. Ma questo può essere fatto tramite un'altra semplice istruzione SQL. Ho essenzialmente scritto la mia libreria per rafforzare questo tipo di relazioni, poiché tutto deve essere fatto manualmente. Devo dire, tuttavia, che l'efficienza di SQLite e SQL nel suo insieme rende questo molto semplice e veloce.

In sostanza, il processo per qualsiasi relazione imposta va come segue:

  • In una query che richiede una chiave esterna, usare un JOIN.
  • In un INSERT utilizzare un CONSTRAINT sul campo chiave esterna NOT NULL
  • In un UPDATE sul campo chiave primaria è una chiave esterna in un'altra TABLE, eseguire una seconda UPDATE sulla corrispondente TABLE che ha la chiave esterna. (CASCADE UPDATE)
  • Per un DELETE con gli stessi parametri, fare un'altra DELETE con il quale essendo foreign_key = _id (assicuratevi di avere il _id prima di DELETE fila, prima).

Android 2.2+

chiavi esteri è supportato, ma è disattivata per impostazione predefinita. In primo luogo è necessario accenderli:

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

successivo è necessario creare la relazione TRIGGER. Questo viene fatto quando si crea TABLE anziché una singola istruzione TRIGGER separata. Vedi sotto:

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

Per ulteriori informazioni su SQLite e le sue capacità, controlla SQLite official site. Questo è importante in quanto non disponi di tutti gli JOIN s che fai in altri RDBMS. Per informazioni specifiche sulle classi SQLite in Android, leggi the documentation.

+0

Che risposta scoppiettante, grazie.Conosco molti database (MySQL, MSSQL, Postgres, Ingres, SQLite per nominare alcune e molte lingue), ma questa è la mia prima app per Android e ho dimenticato di più su JAVA di quanto mi importi davvero ammettere, What I ' Mi sto davvero adoperando per la sintassi specifica di Android e avrei dovuto renderlo più chiaro nella mia domanda, ma hai evidenziato alcune gravi lacune nelle mie conoscenze, specialmente quando si attiva fk. Accetterò la tua risposta poiché ora ho abbastanza informazioni per esprimere domande più specifiche e sono sicuro che gli altri troveranno questo estremamente utile. Grazie ancora – jamesc

+0

Prego. Grazie anche a te. –

5

Come per la prima domanda: non è necessario creare provider di contenuti per ogni tabella. È possibile utilizzare in più tabelle, ma la complessità del provider è aumentata con ogni tabella.

+0

Grazie, non voglio contrassegnare la tua domanda come risposta poiché non ho risposte a tutte le mie domande ma le tue informazioni sono molto apprezzate – jamesc

+0

Prego. –

1

Un fornitore di contenuti è approssimativamente equivalente al concetto di un database. Avresti più tabelle in un database, quindi avere più tabelle nel tuo fornitore di contenuti ha perfettamente senso.

Uno o più rapporti possono essere gestiti come in qualsiasi altro database. Utilizza i riferimenti e le chiavi esterne come faresti con qualsiasi altro database. Puoi usare cose come CASCADE ON DELETE per assicurarti che i record vengano cancellati quando anche i record che fanno riferimento ad altre tabelle vengono cancellati.

Problemi correlati