Riprendendo mano a progetti passati, magari sviluppati da altri, capita spesso di notare qualche scelta di design non troppo efficiente, ma quando ci si trova davanti ad un design talmente sbagliato da compromettere un futuro tranquillo del progetto il problema non è facile da risolvere. Esiste una soluzione?
C'era una volta...
Immaginiamo di avere una grande industria di produzione. Varie macchine di questa industria (di varie tipo, anno, tecnologia e marca) forniscono all'esterno dei dati in basi dati differenti. La nostra applicazione si integra con tutti questi sistemi accedendo ad ognuna di queste e trasferendo i dati che ci interessano all'interno di un database centralizzato Microsoft SQL Server.
Vi presento il grafico
Parliamo dei dati che ci interessano e che interessano il cliente: allarmi, parametri e grafici. Informazioni contenute in determinate tabelle separate ed organizzate secondo uno schema entità-relazione. Vediamo proprio nel particolare una delle tante tabelle: i grafici. La tabella dei grafici può essere vista come un tabellone immenso costituito da un identificativo univoco del lotto di produzione, un valore di tempo e uno o più valori delle grandezze che formano il grafico.
Cattivo Design, Cattivo!
Ma dov'è il cattivo design? Arriviamo al punto: Nella tabella dei grafici non esiste chiave primaria. "Poco importa" direbbe qualcuno, il problema è che quando una tabella non ha nessuna chiave primaria è formalmente possibile effettuare l'inserimento di un record identico ad uno già presente nel database. OPS! L'operazione di discriminazione dei record "buoni" da quelli "doppioni" dovrebbe avvenire nel programma di import a questo punto ma non succede nemmeno qui. DOPPIO OPS!
Ma una SELECT DISTINCT no?
Ok, ci siamo scordati una chiave primaria e pure di importare con criterio le informazioni, avremo dei record duplicati quindi, basta una SELECT DISTINCT a risolvere il problema no? La situazione (peggiore) è che abbiamo un lotto con più di 6000 record identici, una SELECT DISTINCT provoca un BUCO NERO nelle performance di SQL Server quando si tratta di così tanti record.
Possiamo sistemarlo?
Ok ho capito, qual'è la soluzione? Tecnicamente la soluzione sarebbe quella di inserire come chiave primaria la coppia lotto-data in modo tale da non duplicare le informazioni. Il problema è che in SQL Server (come in quasi tutti gli RDBMS) per fare un'operazione di questo tipo è necessario eliminare e ricreare just-in-time la tabella cosa che non può essere fatta dato che ci sono MOLTISSIMI record duplicati nella tabella. A questo punto l'unica speranza è di spostare la vecchia brutta tabella e creare una nuova "moderna" in cui importare i dati.
La soluzione definitiva
La soluzione in definitiva non esiste. Se per "soluzione" si intende creare una nuova tabella ed effettuare una migrazione, questa non può essere applicabile in un'ottica di produzione 24h. L'unica cosa che si può fare è aumentare il timeout di esecuzione delle query ed aspettare il primo fermo produzione previsto per Natale o Capodanno prossimo.
Nessun commento:
Posta un commento