Sto sviluppando un progetto sul lavoro per il quale ho bisogno di creare e mantenere Tabelle di riepilogo per motivi di prestazioni. Credo che il termine corretto per questo è Viste materializzate.Metodo preferito per viste materializzate (tabelle di riepilogo) con MySQL
ho 2 motivi principali per farlo:
Denormalizzazione
Ho normalizzato i tavoli, per quanto possibile. Quindi ci sono situazioni in cui dovrei unire molte tabelle per estrarre dati. Lavoriamo con MySQL Cluster, che ha prestazioni piuttosto scarse quando si tratta di JOIN.
Quindi ho bisogno di creare tabelle denormalizzate in grado di eseguire SELECT più veloci.
riepilogare i dati
Per esempio, ho una tabella transazioni con un paio di milioni di dischi. Le transazioni provengono da diversi siti Web. L'applicazione deve generare un report per visualizzare i conteggi delle transazioni giornaliere o mensili e gli importi totali delle entrate per sito Web. Non voglio che lo script del report lo calcoli ogni volta, quindi ho bisogno di generare una tabella di riepilogo che presenterà una suddivisione per [sito, data].
Questo è solo un semplice esempio. Ci sono molti diversi tipi di tabelle riassuntive che ho bisogno di generare e mantenere.
In passato ho eseguito queste operazioni scrivendo diversi script di cron per mantenere aggiornata ogni tabella di riepilogo. Ma in questo nuovo progetto, spero di implementare una soluzione più elegante e corretta.
Preferirei una soluzione basata su PHP, poiché non sono un amministratore di server e mi sento il più comodo quando posso controllare tutto tramite il mio codice applicazione.
Soluzioni che ho considerato:
copia del VISTA
Se la tabella risultante può essere rappresentato come una singola query SELECT, posso generare una VISTA . Dal momento che sono lenti, ci può essere un cronjob che copia questa VISTA in una tabella reale.
Tuttavia, alcune di queste query SELECT possono essere così lente che non è accettabile nemmeno per i cronjob. Non è molto efficiente ricreare tutti i dati di riepilogo, se le righe più vecchie non vengono nemmeno aggiornate molto.
Cronjobs personalizzate per ogni tabella Riassunto
Questa è la soluzione che ho usato prima, ma ora sto cercando di evitare, se possibile. Se ci saranno molte tabelle riassuntive, può essere difficile da mantenere.
MySQL Trigger
E 'possibile aggiungere trigger alle tabelle principali in modo che ogni volta che c'è un INSERT, UPDATE o DELETE, le tabelle riassuntive vengono aggiornati di conseguenza.
Non ci sarebbero cronjobs e i riassunti sarebbero in tempo reale. Tuttavia, se è mai necessario ricostruire una tabella di riepilogo da zero, dovrebbe essere eseguita con un'altra soluzione (probabilmente la # 1 sopra).
Utilizzando ORM Ganci/Trigger
Sto usando Doctrine come la mia ORM. C'è un modo per aggiungere listener di eventi che attiveranno roba su INSERT/UPDATE/DELETE, che a sua volta può aggiornare le tabelle di riepilogo. In un certo senso questa soluzione è simile alla # 3 sopra, ma avrò un controllo migliore su questi trigger poiché saranno implementati in PHP.
Considerazioni di attuazione:
completo ricostruisce
voglio evitare di dover ricostruire le tabelle di sintesi, per l'efficienza, e solo aggiornamento per nuovi dati Ma nel caso qualcosa vada storto, ho bisogno della capacità di ricostruire la tabella di riepilogo da zero usando i dati esistenti sulle tabelle principali.
Ignorando UPDATE/DELETE su dati vecchi
Alcuni riepiloghi possono assumere che le registrazioni più vecchie non saranno mai aggiornati o cancellati, ma verranno inseriti solo i nuovi record. Il processo di riepilogo può far risparmiare parecchio lavoro ipotizzando che non sia necessario verificare la disponibilità di aggiornamenti su dati meno recenti.
Ma ovviamente questo non si applica a tutti i tavoli.
tenere un registro
Supponiamo che io non avere accesso, o non vogliono utilizzare i registri MySQL binari.
Per riepilogare i nuovi dati, il processo di riepilogo deve solo ricordare gli ultimi ID della chiave primaria per gli ultimi record riepilogati. La prossima volta che viene eseguito, può riepilogare ogni cosa dopo quell'ID. Tuttavia, per tenere traccia dei vecchi record che sono stati aggiornati/cancellati, ha bisogno di un altro registro in modo che possa tornare indietro e riassumere questi dati.
Gradirei qualsiasi tipo di strategie, suggerimenti o link che possono aiutare. Grazie!
Le viste materializzate sono viste che possono essere indicizzate (denominate "viste indicizzate" nella terminologia TSQL/SQL Server). Sono notoriamente limitati nelle funzionalità e MySQL non li supporta. MySQL supporta a malapena le visualizzazioni non materializzate, confrontando la funzionalità con altri fornitori. Oracle è l'unico altro DB che conosco che supporti visualizzazioni materializzate, oltre a SQL Server. Mi aspetto che DB2 funzioni, ma PostgreSQL no. –