Una serie (per lo più) in tre parti
La metodologia descritta in Evolutionary Database Design e operazionalizzata in Refactoring Databases: Evolutionary Database Design è chiara da vent'anni. Le sette pratiche, il catalogo di oltre 70 refactoring nominati, le meccaniche di transizione – tutto documentato, revisionato paritariamente, insegnato.
Quella metodologia ha raggiunto CI/CD nel 2010 con Continuous Delivery (Capitolo 12: Gestione dei dati). Le migrazioni sono diventate artefatti di prima classe nella pipeline di distribuzione. La disciplina dei cambiamenti del database come codice ha raggiunto il movimento CI/CD più ampio. Ciò che CD non ha risolto è l'isolamento per pipeline: le pipeline potevano eseguire migrazioni, ma necessitavano ancora di un database di destinazione, e questa destinazione era condivisa. La pratica n. 4 – Ognuno ottiene la propria istanza di database – è rimasta aspirazionale per la maggior parte dei team perché i veri database per sviluppatore a forma di produzione costano tempo, denaro e cicli di DBA. Lo strato compensativo emerso per aggirare il divario (oggetti mock, ambienti di staging condivisi, sostituti di database in memoria, code di ticket DBA) è diventato metodologia fondamentale per impostazione predefinita, non per progettazione.
Nel 2026, il branching del database copy-on-write arriverà in Databricks Lakebase. Un branch di un database di produzione su scala terabyte, che dura un secondo e non occupa spazio alla creazione, è ora un'operazione O(1). Il vincolo che manteneva la Pratica #4 aspirazionale è stato rimosso.
Questa serie descrive cosa cambia quando il vincolo viene rimosso: non la metodologia – quella rimane – ma le pratiche che emergono per la prima volta, la governance su scala di team che diventa automatica, l'evoluzione del ruolo del DBA e il nuovo substrato che gli agenti condividono con le loro controparti umane.
Jen è il personaggio sviluppatore del saggio Evolutionary Database Design. In quel saggio ha implementato un refactoring del database – la suddivisione di un inventory_code campo in location_code, batch_number e serial_number – come una normale user story, illustrando che DBA e sviluppatori possono collaborare, gli schemi possono evolvere in piccoli incrementi e le migrazioni portano avanti il cambiamento in sicurezza.
La serie riprende con Jen vent'anni dopo. La metodologia che segue è la stessa che seguiva nel 2003. Ciò che è nuovo è il substrato sotto il suo flusso di lavoro: il branching del database copy-on-write, che rende operative le pratiche che stava leggendo su scala di produzione. Attraverso le tre parti di questa serie, è la stessa Jen in tre ambiti: la sua giornata (Parte 1), il suo nuovo playbook (Parte 2) e il suo team (Parte 3).
Per capire come funziona, ripercorriamo il viaggio di come una sviluppatrice di nome Jen implementa un'attività che afferma che l'utente dovrebbe essere in grado di vedere, cercare e aggiornare la posizione, il lotto e il numero di serie di una produzione in inventario.
Quanto segue descrive i vari passaggi che Jen deve compiere per completare questa attività, descrivendo i passaggi cercheremo di confrontare come cambia il flusso di lavoro di Jen quando lavora con database tradizionali e utilizzando Lakebase che consente il branching del database a costi minimi.
Jen affronta quella che sembra una funzionalità semplice. Il team di prodotto vuole consentire agli utenti di acquisire la posizione, il lotto e il numero di serie di un articolo durante l'aggiunta all'inventario e utilizzarli successivamente nel flusso dell'applicazione. Dall'esterno, il cambiamento sembra piccolo: aggiungere un campo allo schermo, salvare il valore, mostrarlo nella schermata Inventario per un articolo e magari usarlo in una decisione downstream in seguito.
Per Jen, il cambiamento dell'applicazione è facile da immaginare. Sa dove si trova il modulo. Sa quale servizio gestisce la richiesta. Vede l'oggetto modello che necessita di attributi aggiuntivi. Ma nel momento in cui ripercorre il cambiamento fino in fondo, vede la vera dipendenza: anche il database deve cambiare.
Sono necessarie alcune nuove colonne, i dati esistenti nell'ambiente di produzione devono essere preservati e devono essere semanticamente corretti. L'applicazione deve gestire dati vecchi e nuovi in sicurezza e lei deve aggiungere test per dimostrare che i nuovi campi vengono archiviati, letti e visualizzati correttamente. Quella che sembrava una semplice funzionalità è ora un cambiamento coordinato dell'applicazione e del database, con la responsabilità aggiunta di garantire che lo schema e i dati di produzione esistenti vengano migrati al nuovo schema.
Jen crea un branch di codice per il lavoro che sta per intraprendere e, poiché stanno utilizzando un database condiviso e il resto del team sta utilizzando lo stesso database per lo sviluppo, inizia immediatamente a pensare a tutte le modifiche che introdurrà nel livello del database che potrebbero influire su altri utenti del database condiviso e inizia a pianificare come renderla sicura per gli altri. Potrebbe eseguire la modifica dell'applicazione localmente ed essere in grado di eseguire i suoi test unitari e di integrazione? Ogni opzione ha dei costi. Può aspettare. Può chiedere al team di coordinarsi. Può configurare il proprio Postgres locale in Docker, popolarlo con un pg_dump obsoleto di una settimana fa e sperare che le differenze non contino. Può ripiegare sull'esecuzione di un database locale in un container o su un database in memoria H2 o SQLite che funziona velocemente ma utilizza il dialetto sbagliato, quindi i suoi test passano localmente e mostrano fallimenti sconosciuti su Postgres reali. Può persino testare i suoi script di migrazione dello schema e dei dati? Questa paura di rompere il lavoro altrui la rallenta e allo stesso tempo non le permette di sperimentare con diverse opzioni di costruzione della funzionalità.
Poiché in un database condiviso, uno sviluppatore potrebbe testare una modifica della logica di business, un altro sta eseguendo il debug di una migrazione dati, qualcun altro ha creato dati di test che Jen non capisce. Se Jen applica la sua modifica dello schema al database condiviso, potrebbe rompere il lavoro di qualcun altro. Se qualcun altro cambia lo schema mentre lei sta testando, i suoi risultati potrebbero non essere più affidabili. Se aggiunge dati di test, potrebbe interferire con le ipotesi di un altro sviluppatore.
Jen può aspettare finché il database condiviso non è libero, il che protegge il team dalle collisioni, ma trasforma una piccola funzionalità in un problema di pianificazione e una perdita di produttività. Può coordinarsi manualmente con gli altri sviluppatori: “Stai usando dev in questo momento?” “Posso eseguire una migrazione?” “Per favore, non resettare i dati per la prossima ora.” qualcosa come un testimone in una staffetta. Funziona per un po', ma non scala, specialmente con un team remoto o in fusi orari diversi.
Jen pensa a un'altra opzione, usando un database locale in memoria, sa che questa configurazione non corrisponde allo stato del database utilizzato dal resto del team, il che significa che non avrà fiducia nella sua soluzione poiché la modifica potrebbe funzionare localmente e fallire ancora più tardi quando incontra i dati e lo schema reali in ambienti superiori come staging e produzione.
Il vero problema che Jen sta incontrando è del feedback più lento può apportare la modifica, ma scoprire se la modifica funziona, ma un feedback rapido e realistico e senza questo feedback il cambiamento del database diventa qualcosa che il team tratta con attenzione e finisce per scegliere la prima soluzione che funziona e non sperimenta mai o prova soluzioni multiple, portando così a soluzioni subottimali, produttività ridotta e sviluppatori insoddisfatti.
Utilizzando Lakebase, Jen ha la possibilità di creare un branch di un database per il suo uso individuale e questa capacità cambia completamente il suo modo di lavorare.
Invece di aspettare che il database di sviluppo condiviso diventi disponibile, Jen crea un branch del database databricks postgres create-branch per la sua funzionalità o utilizzando un Estensione VS Code / Cursor. Questo cambia immediatamente la forma del lavoro. Non chiede più al team una finestra di tempo. Non negozia più con altri sviluppatori su chi può eseguire quale migrazione e quando. Non cerca più di proteggere la sua modifica non finita dalle modifiche non finite di tutti gli altri. Ha il suo spazio di database isolato, creato dallo stesso tipo di ambiente di database che l'applicazione utilizzerà alla fine in produzione.
Il branch fornisce a Jen una copia veloce dello stato del database su cui lavorare. Ora ha lo stesso motore Postgres, lo stesso schema, le stesse policy di governance e gli stessi dati a forma di produzione che vedrebbe se interrogasse la produzione direttamente. L'unica differenza: questo branch può essere modificato, scartato o ricreato senza influire su alcun altro carico di lavoro. Non sta testando contro un database locale semplificato che si comporta in modo diverso dalla produzione. Sta lavorando con lo stesso tipo di database che il team utilizza in produzione, con gli stessi tipi di regole di schema, vincoli, indici, dati di riferimento e cronologia delle migrazioni che fanno sì che le modifiche al database abbiano successo o falliscano nel mondo reale. Quel realismo è importante perché molti problemi del database non appaiono nei test unitari isolati. Appaiono quando una nuova migrazione incontra la struttura esistente, i dati esistenti, le ipotesi esistenti e il comportamento dell'applicazione esistente.
Ora Jen può trattare la modifica del database come parte della progettazione, non solo come un passaggio di distribuzione. Può provare prima la versione ovvia: aggiungere le nuove colonne, impostare una logica predefinita per dividere la colonna esistente, creare uno script di migrazione del database, aggiornare l'applicazione ed eseguire i test. Quindi può porre domande migliori. Questo script di migrazione dovrebbe funzionare per i volumi di dati di produzione, la qualità dei dati in produzione è quella che i suoi script si aspettano? Uno script di migrazione dati nasconde informazioni aziendali mancanti? La preferenza dovrebbe essere modellata come semplici colonne, una tabella di lookup o una tabella di item_information separata perché è probabile che arrivino più informazioni in seguito? Il modello di query richiederà un indice? Questo design renderà la reportistica downstream più facile o più difficile? Nel vecchio flusso di lavoro, queste domande spesso vengono compresse perché la modifica del database è costosa.
Nel flusso di lavoro con branch, Jen può esplorarli mentre la funzionalità è ancora in fase di definizione. Il DBA può affiancarla per guidarla sulle sfumature della produzione e sui volumi di dati, fornendo così un prezioso input nella progettazione della soluzione invece di essere un revisore a posteriori.
Jen scrive lo script di migrazione. Qualunque cosa usi il suo team – Flyway, Liquibase, Alembic, Knex, Prisma – lo script vive nel repository di codice, accanto alle modifiche dell'applicazione. Schema e migrazione dati viaggiano con il codice.
(Questo è il refactoring Split Column – uno dei circa 70 pattern catalogati in Refactoring Databases, il libro che ha reso operative le sette pratiche.)
Applica la migrazione al suo branch utilizzando flyway migrate. Lo strumento viene eseguito in meno di un secondo su dati a forma reale. Aggiorna il codice del suo repository per leggere e scrivere le tre nuove colonne. Esegue la sua suite di test. I test passano contro un vero Postgres, senza mock, senza sostituti in memoria.
Se desidera una base pulita per provare un approccio diverso, scarta il branch e ne crea uno nuovo dalla produzione. Un altro secondo. Nessun ticket di pulizia. Nessun DBA coinvolto.
La stessa Jen. Lo stesso refactoring. Ciò che è cambiato è la capacità.
La capacità di sperimentare è importante. La progettazione e lo sviluppo evolutivo non riguardano solo il muoversi rapidamente attraverso una checklist predefinita. Riguarda anche l'apprendimento man mano che il lavoro diventa più concreto. Jen potrebbe scoprire che il primo design dello schema funziona ma crea una logica applicativa scomoda. Potrebbe scoprire che il secondo design è più pulito ma rende più complicata la migrazione dei record esistenti. Potrebbe scoprire che una piccola decisione di normalizzazione ora renderebbe più facili le modifiche future. Il primo script di migrazione che ha scritto, gli indici SUBSTRING sono sfasati di uno. Il DROP COLUMN distruttivo è stato eseguito prima che potesse verificare che le nuove colonne fossero state popolate correttamente. Poiché ha il suo branch, queste scoperte sono poco costose. Può applicare una migrazione, eseguire l'applicazione, ispezionare i dati, avanzare con un'altra migrazione o resettare e provare un percorso diverso.
Il branch cambia anche la postura emotiva del lavoro. Jen non deve essere eccessivamente cauta perché qualcun altro potrebbe dipendere dal database di sviluppo condiviso. Non deve annunciare ogni esperimento al team. Non deve ripulire immediatamente i dati di test perché un altro sviluppatore potrebbe inciamparci sopra. Il suo branch è un luogo sicuro per il pensiero incompiuto. Può contenere tabelle temporanee, tentativi di migrazione falliti, dati di test scomodi e progetti abbozzati senza creare disturbo a nessun altro.
Allo stesso tempo, l'isolamento non significa distacco dagli standard del team. Jen scrive ancora script di migrazione. Mantiene ancora il codice dell'applicazione e la modifica del database insieme. Esegue ancora i test. Si aspetta ancora che il design finale venga rivisto. La differenza è che può fare la parte disordinata del lavoro privatamente e rapidamente prima di chiedere al team di ragionare sulla versione lucidata. Al momento di aprire una pull request, la conversazione può concentrarsi sul fatto che il design sia corretto, non sul fatto che avesse un posto sicuro per testarlo.
Questo è il cambiamento chiave: il branch del database fornisce a Jen un feedback veloce, realistico e isolato che può anche essere rivisto dai suoi tech lead o DBA, mostrandole il suo branch del database. Veloce significa che può creare l'ambiente quando ne ha bisogno, non quando qualcuno glielo fornisce. Realistico significa che sta testando contro lo stesso tipo di comportamento del database che conta in produzione. Isolato significa che i suoi esperimenti non interrompono nessun altro. Insieme, queste tre proprietà trasformano la modifica del database da un collo di bottiglia a una parte normale dello sviluppo delle funzionalità.
Jen può ora portare avanti insieme l'applicazione e il database. Il suo branch di codice e il suo branch di database diventano due facce della stessa attività. Uno contiene le modifiche all'applicazione. L'altro fornisce a tali modifiche un database reale su cui vivere. Invece di aspettare, coordinarsi o fingere con una configurazione semplificata, Jen può progettare, testare, rivedere e imparare. La funzionalità è ancora piccola, ma ora il database non è più ciò che la rallenta.
Jen esegue il commit sia del codice dell'applicazione che dello script di migrazione. Apre una PR.
La CI fa ciò che Jen ha appena fatto, ma per il team: crea il proprio branch temporaneo di Lakebase, applica la migrazione, esegue la suite di test dell'applicazione, esegue test del database sullo schema migrato, valida la migrazione stessa (si applica in modo pulito, idempotente, reversibile) e pubblica un commento schema-diff sulla PR che mostra esattamente quali oggetti del database sono cambiati.
Il revisore può ora vedere cosa fa la modifica dello schema inline con il codice che la utilizza, cambiando la loro comprensione contestuale da astratta a concreta.

Screenshot della vista Branch Diff Summary dall'Estensione Lakebase SCM
Nel vecchio flusso di lavoro, la domanda sulla revisione del database era "questo bloccherà il database?" – approvata da un DBA che doveva esaminare ogni modifica in isolamento perché ogni modifica aveva conseguenze su scala di produzione se sfuggiva al controllo. Le revisioni erano sincrone. Gli orari si scontravano. Il calendario del DBA diventava una coda e a volte il DBA veniva saltato per motivi di "Time to Market".
Nel nuovo flusso di lavoro, la domanda è "questo è il design giusto?" Il DBA ha già visto il diff dello schema pubblicato dalla CI. Ha già visto la migrazione eseguita con successo su un branch con dati reali. Jen può anche coinvolgere il DBA per una discussione, per mostrare cosa sta pensando e tutte le altre opzioni che ha provato. Il DBA può rivedere secondo il proprio orario, non quello di Jen. Possono fornire una revisione molto prima nel ciclo di sviluppo della soluzione e migliorare la soluzione in termini di integrità dei dati, strategia di indicizzazione, estensibilità futura o manutenibilità a lungo termine, non sul controllo protettivo che prima occupava tutto il loro tempo.
Il team rivede codice e database insieme. Un PR. Una conversazione. Stessa finestra.
La migrazione è già stata testata su un branch con dati reali. L'applicazione è già stata eseguita sullo schema modificato. La migrazione dello schema è stata revisionata. La build CI ha eseguito esattamente gli stessi passaggi ed è stata verde per un'ora.
Quando Jen esegue l'unione, la migrazione viene applicata all'ambiente successivo, i branch per il database e il codice per l'ambiente CI e Jen vengono ripuliti. Garantendo così che la modifica del database non sia più una sorpresa alla notte del rilascio.
Ciò che Jen ha appena fatto è la quinta pratica del saggio del 2003: integrazione continua delle modifiche al database.
La modifica del database diventa parte dello sviluppo normale. Il branching riduce l'attesa, il rischio e l'overhead di coordinamento. Il loop giornaliero di Jen ora le fornisce un feedback rapido e isolato a livello di database.
Nella Parte 2 – Il Nuovo Playbook di Jen, spieghiamo cosa ha sollevato e perché il layer compensativo su cui Jen ha lavorato per tutta la carriera può essere rimosso: il branching copy-on-write, l'architettura che lo rende possibile e le ottimizzazioni metodologiche che ne derivano.
Nella Parte 3 – Il Team di Jen su Scala, esaminiamo come appare la storia di Jen quando è una sviluppatrice tra cinquanta, o forse sta lavorando su un prodotto white-labeled, o sta lavorando su un monolite modulare con molti domini al suo interno – governance alla creazione del branch, il reframe del DBA, l'agente in loop e il lavoro di progettazione della piattaforma che si apre quando il calendario del DBA non è una coda di ticket.
Per i lettori che desiderano un tour degli strumenti IDE che Jen ha utilizzato in questo post, c'è il Companion: Plugin Walkthrough – l'estensione Lakebase SCM per VS Code / Cursor, end-to-end.
Infine, a breve verranno rilasciati un Lakebase App Dev Kit per gli agenti e un ebook per gli esseri umani.
(Questo post sul blog è stato tradotto utilizzando strumenti basati sull'intelligenza artificiale) Post originale
Iscriviti al nostro blog e ricevi gli ultimi articoli direttamente nella tua casella di posta.