Va bene strutturare una tabella non normale nel database relazionale per ottenere una query veloce?

4

Diciamo che abbiamo 3 entità qui, User, Tag, Track e una singola entità associativa chiamata Tagged.

Ho bisogno di contare una frequenza tag di una traccia e il modo comune è contare il record di taggato, ma cosa succede se ho solo archiviato la frequenza del tag come attributo intero sull'entità Tag e mantengo il valore ogni volta che ci sono modificato sul record di Tagged, sarà un problema?

Modifica:
Il DBMS che sto usando è MySQL 5.6.
Informazioni sul set di dati, ci sono 947 tracce, 7962 tag, 800 ~ utenti e 366617 tagged

Perché devo interrogarlo velocemente? Perché, sto cercando di calcolare il valore di similarità tra ogni traccia e in quel processo ho bisogno di ottenere la frequenza di ogni tag delle tracce che sto calcolando e penso che la query lenta sia dove dovrebbe ottenere la frequenza dal conteggio del record su Tagged, è per questo che penso che forse dovrei semplicemente memorizzare la frequenza invece di contare attraverso quei record.

    
posta Edwin Harly 11.08.2018 - 05:56
fonte

2 risposte

3

Devi registrare le informazioni derivabili solo quando assolutamente necessario, dopo che è stato osservato che una query o una vista sulla tabella Tagged non è pratica.

Tuttavia, una volta presa la decisione di memorizzare queste informazioni, la registrazione delle informazioni derivabili va bene, a condizione di mantenere la coerenza. Considera l'implementazione come trigger sulla tabella Tagged per garantire coerenza a livello di database, in modo che le modifiche dirette al database (ad esempio, da parte di un DBA) non possano rompere i tuoi dati.

A proposito, la tua entità associativa dovrebbe essere solo una relazione ternaria. Le entità associative nel modello ER sono richieste solo quando una relazione deve essere oggetto di un'altra relazione.

    
risposta data 11.08.2018 - 07:43
fonte
4

Non consiglierei di farlo.

Complifica il database con ciò che è essenzialmente un valore memorizzato nella cache o un rapporto.

Un valore memorizzato nella cache può essere mantenuto al di fuori del database

Un report dovrebbe essere fatto su un server di report.

Vorrei specialmente non raccomandare l'uso di trigger per mantenere aggiornato il valore. Questo potrebbe rallentare davvero il tuo db.

La tua applicazione potrebbe utilizzare un numero qualsiasi di aggregati e calcoli diversi, aggiungerai ognuno come una colonna in più su un tavolo?

Eseguire la query aggregata e memorizzare nella cache il risultato nell'applicazione (invalidando quando richiesto) oppure eseguire un report ogni giorno e utilizzarlo.

Nel complesso aggiungere la colonna in più è una soluzione molto incentrata sul database. Se hai un livello applicazione o API sopra il database avrai a disposizione più opzioni per evitare questo problema.

Ad esempio, se recupero sempre una traccia e i relativi tag insieme per popolare un oggetto aggregato, non è necessario calcolare il numero di tag nel database.

Se voglio mostrare il numero di tag al giorno, a settimana, ecc., una sola colonna della tabella traccia non mi aiuta più. Posso interrogare Track + i tag di oggi dal DB di transazione e la frequenza Tag nel tempo per quella traccia dal cubo di segnalazione che sarà ottimizzato per quel tipo di query sui dati storici.

Anche se desidero un on demand fino al secondo report delle tracce Tagged più frequentemente in ogni momento, per il quale sarebbe utile una singola colonna aggiornata. Non aggiungerei ancora la colonna. Invece avrei l'applicazione sollevare un evento quando è stato aggiunto un tag e gestirlo in una soluzione completamente separata, possibilmente statsd o un cubo di reporting a cui scriverei direttamente.

    
risposta data 11.08.2018 - 09:44
fonte

Leggi altre domande sui tag