Progettazione del database: stato di archiviazione o stato di elaborazione ogni volta?

15

Diciamo che ho un'applicazione di database relazionale e un oggetto "utente" e un oggetto "messaggio". Ora voglio mostrare il numero di messaggi non letti a questo utente.

Qual è il modo migliore per archiviarlo? Devo introdurre un campo nell'utente e contarlo se l'utente riceve un messaggio e diminuisce il conteggio se ne legge uno? Oppure eseguo una query ogni volta per calcolare il numero di messaggi per l'utente che sono contrassegnati come non letti?

Penso che il primo approccio sia più complicato e soggetto a errori, ma che migliori il secondo approccio.

Come si fa normalmente o qual è l'approccio migliore?

    
posta jan 24.06.2014 - 12:31
fonte

4 risposte

14

How is this normally done or whats the better approach?

L'approccio migliore è provarlo prima senza un campo aggiuntivo, misurare le prestazioni e se risulta davvero troppo lento, si tenta di ottimizzare. Questo potrebbe significare passare al primo approccio usando un campo extra, ma dovresti considerare di testare anche altre opzioni, ad esempio inserendo un indice extra nei campi combinati ("non letti", "userID") sui tuoi messaggi.

    
risposta data 24.06.2014 - 12:48
fonte
9

La soluzione da manuale secondo la teoria del database non dovrebbe avere valori nel tuo database che dipendono dai valori di altri dati, poiché si tratta di dipendenze transitive . Avere campi che sono valori calcolati in base ad altri campi è una violazione della normalizzazione, perché porta a informazioni ridondanti.

Tuttavia, a volte ciò che dice il libro di testo e qual è il metodo più pratico nella pratica differiscono. Il conteggio del numero di messaggi non letti ogni visualizzazione di pagina potrebbe essere un'operazione piuttosto costosa. Memorizzare il numero nella tabella user sarebbe molto meglio per le prestazioni. Il costo sarebbe che è possibile che esistano incongruenze nel database: Potrebbe essere possibile che un messaggio venga eliminato, aggiunto o letto senza ricordare di aggiornare anche il contatore non letti.

    
risposta data 24.06.2014 - 13:03
fonte
4

Il potenziale problema sono le prestazioni e non hai ancora un problema di prestazioni. Ci sono molte cose che puoi fare a seconda del database scelto per gestirlo nella soluzione n. 1: indicizzazione, hardware, memorizzazione nella cache, ecc. Tutto dipende dalla frequenza con cui l'utente ha bisogno di ottenere un conteggio di messaggi non letti. Molte di queste scelte non richiedono la codifica personalizzata sul lato app, quindi è possibile implementarle con un cambio di codice o molto poco. Rende più facile crescere con l'app.

Una volta che un utente si connette / accede, ottenere il conteggio dal database una volta non è poi così male. La tua app manterrà un elenco di messaggi in costante aggiornamento come la posta elettronica? Ottenere un conteggio non letto da qui non richiede un altro viaggio nel database e per ottenere nuovi messaggi farà comunque un viaggio in db.

Fai un salto nel db ogni volta che un messaggio viene letto per segnalare IsRead? il campo è sufficiente senza ricalcolare un altro campo.

Con la soluzione # 2 (mantenendo un conteggio in un campo / su disco), avrai bisogno di una routine per ricostruire / ricalcolare periodicamente questo campo quando c'è un problema? E ci sono sempre problemi. Hai intenzione di concludere tutto questo in una transazione? Ogni volta che qualcuno invia a qualcun altro un messaggio, potrebbe non riuscire perché non può aggiornare UnreadCount dell'utente destinatario a causa di un blocco della tabella Utente? O stai per creare una tabella separata per questo campo?

    
risposta data 24.06.2014 - 13:55
fonte
0

Il modo in cui lo farei è eseguendo una query ogni volta, cioè il tuo secondo approccio. Assicurati di aggiungere un indice nella tabella dei messaggi nella colonna che funge da chiave esterna per la tabella degli utenti per migliorare le prestazioni della query.

Quindi, come dice Doc, misura le prestazioni di questo approccio e poi sarai in grado di dire se devi seguire un percorso diverso.

    
risposta data 24.06.2014 - 12:54
fonte

Leggi altre domande sui tag