Ingegneria del software
Evolvere lo schema del database senza interrompere il software
Un aggiornamento applicativo può terminare in pochi minuti, mentre i dati che utilizza continuano a vivere per anni. Quando cambia una tabella, il problema non riguarda soltanto la correttezza del comando SQL: durante il rilascio possono convivere istanze vecchie e nuove, processi pianificati e integrazioni ancora legate alla struttura precedente. Progettare questa convivenza permette di rendere il cambiamento verificabile. Il punto di partenza è trattare lo schema come un contratto operativo, con una sequenza di passaggi e condizioni di avanzamento esplicite.
Inventariare chi legge e chi scrive prima di cambiare una colonna
Una tabella raramente appartiene soltanto alla schermata che la mostra. Potrebbe essere utilizzata da un servizio notturno, da una vista destinata ai report, da una procedura di esportazione o da un processo di assistenza. Prima di modificare un campo serve quindi un inventario dei consumatori, distinguendo accessi in lettura e in scrittura. Per ciascuno occorre conoscere il responsabile, la versione distribuita e la frequenza di esecuzione. Un componente che parte una volta al mese può sfuggire a una verifica basata soltanto sulle ultime ore.
Il risultato utile è una matrice di compatibilità: quali versioni del codice funzionano con lo schema attuale, con quello intermedio e con quello finale. Le celle devono corrispondere a prove ripetibili, non a supposizioni. Anche le scritture richiedono attenzione: un programma precedente potrebbe continuare a generare record privi del nuovo dato. Se questo comportamento resta consentito, bisogna stabilire chi completerà il record e con quale regola. Se non è consentito, la distribuzione deve impedirlo prima di rendere obbligatorio il campo.
Separare aggiunta, transizione e rimozione
Una strategia frequente consiste nell’ampliare prima la struttura, trasferire poi gli utilizzatori e rimuovere infine ciò che non serve. Supponiamo, come esempio esclusivamente progettuale, di sostituire un codice di stato testuale con un identificativo riferito a una tabella dedicata. Aggiungere la nuova colonna mantenendo la precedente crea uno spazio di transizione. Rinominare direttamente quella esistente obbligherebbe invece tutti i consumatori ad adeguarsi nello stesso momento, compresi quelli che il gruppo potrebbe non avere ancora individuato.
Le indicazioni di sviluppo di GitLab mostrano perché le operazioni sullo schema debbano essere coordinate con le versioni applicative e, per tabelle grandi, distribuite su più passaggi. Il principio può orientare il progetto, ma le procedure specifiche dipendono dal database e dalla piattaforma. Conviene descrivere ogni passaggio con una precondizione, un controllo di completamento e una possibilità di arresto. Finché queste condizioni non sono soddisfatte, il passaggio successivo rimane escluso dal rilascio anche se il nuovo codice è già disponibile.
Assegnare una sola autorità durante la doppia rappresentazione
La presenza contemporanea di due colonne introduce una domanda decisiva: quale rappresenta il valore autorevole? Scrivere entrambe senza una regola comune può produrre divergenze difficili da diagnosticare. Nel nostro esempio, durante la prima fase il codice testuale potrebbe restare la fonte dalla quale derivare il nuovo identificativo. Il progetto deve specificare come avviene questa derivazione e che cosa succede se la corrispondenza non esiste. Inventare automaticamente uno stato pur di completare l’aggiornamento trasformerebbe un problema tecnico in un errore di processo.
Quando è possibile, aggiornare le due rappresentazioni nella stessa transazione riduce le finestre di incoerenza. Trigger e logica applicativa presentano però costi diversi di visibilità, manutenzione e collaudo: la scelta va motivata e assegnata a un responsabile. Se le scritture attraversano sistemi distinti, occorre un protocollo di riconciliazione, con ritardo tollerato ed eccezioni gestibili. La fase transitoria deve avere una scadenza operativa: conservare indefinitamente due fonti equivalenti moltiplica le regole che ogni futura modifica dovrà rispettare.
Completare lo storico con lavorazioni riprendibili
I record esistenti devono essere trasformati senza assumere che la tabella resti ferma. Una lavorazione in lotti dovrebbe identificare intervalli stabili, registrare l’avanzamento e poter ripetere una porzione senza alterare un risultato già valido. Per una tabella che riceve nuovi inserimenti, il solo contatore delle righe elaborate non dimostra la copertura: bisogna distinguere il perimetro iniziale dai record creati durante il lavoro. Servono inoltre regole per le righe modificate mentre il lotto è in corso.
La dimensione dei lotti va provata con volumi e concorrenza rappresentativi. Un aggiornamento corretto può comunque saturare l’archiviazione, aumentare il ritardo delle repliche o peggiorare le richieste interattive. È opportuno definire soglie di rallentamento e arresto, osservando latenza, attese e avanzamento reale. Il completamento richiede una verifica del contenuto: nel nostro esempio, nessuno stato non mappato e nessuna discordanza tra codice originario e identificativo derivato. Un totale di righe uguale prima e dopo non basta a dimostrarlo.
Valutare blocchi, indici e vincoli sulla tecnologia effettiva
Non tutte le modifiche additive hanno lo stesso comportamento operativo. La documentazione PostgreSQL distingue, per esempio, l’aggiunta di una colonna con valore predefinito costante da quella con una funzione volatile: il lavoro necessario può essere molto diverso. La valutazione deve includere versione del motore, tipo di tabella, dipendenze e dimensione dei dati. Un comando rapido su un ambiente vuoto non costituisce una misura utile del suo impatto su una base di produzione utilizzata da molte sessioni.
Anche la creazione di un indice richiede una scelta esplicita. PostgreSQL documenta una modalità concorrente con caratteristiche e limitazioni proprie, compresa la gestione di eventuali indici rimasti non validi dopo un errore. Non è quindi sufficiente aggiungere un’opzione al comando per promettere assenza di interruzioni. Il piano dovrebbe indicare tempi massimi di attesa, controlli preliminari delle transazioni lunghe e criteri di annullamento. I vincoli definitivi vanno introdotti quando i dati e tutti gli scrittori rispettano già la regola attesa.
Collaudare le combinazioni e il ritorno alla versione precedente
Il collaudo più informativo riproduce la sequenza di distribuzione. Si prepara lo schema intermedio, si eseguono operazioni con il codice precedente, si introduce la nuova versione e si osservano letture e scritture durante la convivenza. Vanno inclusi processi differiti, esportazioni e tentativi ripetuti. Nell’esempio degli stati, una prova deve inserire un valore durante il completamento dello storico e verificare quale rappresentazione verrà poi letta. Un’altra deve interrompere il lotto e riprenderlo dal punto registrato.
Il ritorno al codice precedente merita una prova distinta. Potrebbe essere consentito finché la nuova versione continua a produrre dati comprensibili anche alla vecchia; oltre un certo passaggio potrebbe richiedere una conversione aggiuntiva o non essere più praticabile. Il backup resta necessario, ma ripristinare un’intera base può perdere le operazioni successive al salvataggio e richiedere una finestra di servizio. Il gruppo deve conoscere questo confine prima del rilascio, indicando quando sia più ragionevole completare la correzione in avanti.
Rimuovere il vecchio contratto soltanto dopo una verifica positiva
La vecchia colonna può essere eliminata quando nessun componente la usa più e quando esistono evidenze sufficienti a sostenerlo. Una ricerca nel codice aiuta, ma non identifica necessariamente una query esterna o un’esportazione manuale. Occorre incrociare inventario, controlli applicativi e osservazione per un periodo che includa le attività meno frequenti. La rimozione è un cambiamento autonomo, con un proprio responsabile e un piano di esecuzione. Non dovrebbe diventare un dettaglio nascosto nella stessa consegna che introduce il nuovo comportamento.
Questa disciplina riguarda l’evoluzione interna di un prodotto software. Il trasferimento delle informazioni tra applicazioni presenta invece un perimetro organizzativo diverso: per quel contesto è pertinente la guida alla migrazione dei dati verso un gestionale cloud di Gestionale sul Web. Nel progetto tecnico dello schema, la decisione finale resta legata alle evidenze raccolte: compatibilità dimostrata, storico riconciliato, vecchi utilizzatori dismessi e procedure operative realmente eseguibili dal gruppo incaricato.
Riferimenti tecnici
Per approfondire i temi tecnici trattati:
- GitLab: evitare interruzioni durante le migrazioni del database
- PostgreSQL 18: modificare le tabelle
- PostgreSQL 18: creazione degli indici e modalità concorrente
Analisi metodologica originale. L’esempio della trasformazione degli stati è illustrativo e non descrive un cliente né l’architettura interna di Gestionale sul Web. Le procedure operative vanno adattate e provate sul database effettivamente utilizzato.
A cura della redazione tecnica SoftJob. Pubblicato il .
