Database relazionali e sviluppo iterativo

18

In molti approcci allo sviluppo di software come metodologie agili, progettazione orientata al dominio e analisi e progettazione orientata agli oggetti, siamo incoraggiati ad adottare un approccio iterativo allo sviluppo.

Quindi non è previsto che il nostro modello di dominio venga eseguito correttamente la prima volta che iniziamo a lavorare nel progetto. Invece, con il passare del tempo, il modello viene ridefinito perché acquisiamo una conoscenza più approfondita del dominio del problema con il tempo.

A parte questo, anche se proviamo a ottenere un modello perfetto in anticipo, che sono già molto convinto, i requisiti potrebbero cambiare. Quindi, dopo che il software è stato distribuito in produzione, gli utenti finali potrebbero notare che un determinato requisito non era completamente compreso, o, peggio, mancava un requisito.

Il punto qui è che potremmo finire per dover cambiare il modello dopo che il software è stato distribuito. Se ciò accade, abbiamo un problema: il database di produzione contiene dati dell'utente che sono importanti e sono già presenti nel formato del vecchio modello .

L'aggiornamento del codice potrebbe essere un compito difficile se il codice non è ben progettato e se il sistema è grande. Ma può essere fatto con il tempo, abbiamo strumenti come Git che ci aiutano a farlo senza danneggiare la versione pronta per la produzione.

D'altra parte, se il modello cambia, se le proprietà delle classi scompaiono o qualsiasi altra cosa, anche il database dovrebbe cambiare. Ma abbiamo un problema: ci sono già dati che non possono essere persi, che è già stato creato per il vecchio modello.

Sembra che un database relazionale sia una barriera che ci impedisce di fare lo sviluppo iterativo e persino di aggiornare il software quando richiesto dagli utenti.

Un approccio che ho già usato è stato quello di codificare una classe speciale che mappa le vecchie tabelle del database in nuove. Pertanto, queste classi selezionano i dati nel vecchio formato, li convertono nel formato utilizzato dal nuovo modello e salvano nelle nuove tabelle.

Questo approccio sembra non essere il migliore. La mia domanda qui è: esistono approcci ben noti e consigliati per conciliare lo sviluppo iterativo con i database relazionali?

    
posta user1620696 21.02.2016 - 21:05
fonte

3 risposte

15

Non devono essere classi speciali, ma sì, hai bisogno di qualcosa che porti il database nel formato precedente e lo converta in quello corrente.

Il punto è che è necessario sviluppare un processo per scrivere e testare questi script e disciplina per non toccare mai manualmente i database di test e produzione, ma sempre tramite script di migrazione.

Ogni volta che è necessario apportare una modifica al database, si scrive uno script che lo eseguirà, sia in SQL o utilizzando il livello ORM, sia impegnandolo nel controllo della versione insieme alle modifiche che richiedono il nuovo schema. Quindi hai uno script di controllo che aggiornerà il database applicando tutti gli script di migrazione che non sono stati ancora applicati in una sequenza.

E assicurati di modificare sempre e solo gli ambienti di sviluppo, test e QA condivisi applicando gli script e tornando alla versione precedente se non funzionano, quindi puoi essere ragionevolmente sicuro che funzioneranno come previsto quando li scateni sulla produzione.

La nuova installazione viene eseguita semplicemente applicando tutti gli script. Dopo un po ', ne avrete centinaia e penserete che sia molto inefficiente, ma non cadete nella trappola di cercare di ottimizzarlo. L'installazione è un'attività da svolgere una sola volta e mantenerla in modo affidabile e veloce.

@Doc Brown è già collegato Martin Fowler: Design del database evolutivo e link , e aggiungerei Alex Papadimoulis: modifiche al database eseguite a destra , che è più breve e contiene alcuni esempi.

Come esempio decente di strumenti che implementano tale processo, suggerisco Alembic . È basato sul framework Python SQLAlchemy , ma è possibile utilizzarlo con altri linguaggi e framework se non dispongono di un proprio supporto per la migrazione . La pagina di Wikipedia su Migrazione schema elenca altri strumenti simili .

    
risposta data 22.02.2016 - 11:30
fonte
0

Stranamente, questo è il vero problema del mio attuale team di sviluppo. La domanda contiene diverse sotto-domande, quindi saranno affrontate in modo indipendente.

Innanzitutto, un database relazionale limita troppo il modello di dati, rendendo le modifiche molto difficili?

Sicuramente , ma non necessariamente per i motivi citati. Sfortunatamente, la versatilità dei sistemi di gestione dei database relazionali porta anche alla loro caduta. RDBMS è stato originariamente sviluppato per offrire una piattaforma di archiviazione dati relativamente semplice che accetta grandi set di dati e li riduce a dimensioni relativamente ridotte. Ciò è stato fatto a scapito della complessità del modello di dati e della potenza di calcolo richiesta. Con l'aumentare della complessità del database, sono nate le stored procedure, le viste, le funzioni e i trigger per aiutare gli amministratori di database a gestire la complessità in modo coerente e scalabile.

Sfortunatamente, il modello di database relazionale non è orientato agli oggetti e non si associa naturalmente alle entità del mondo reale come dovrebbe fare un modello di dati. Questo ci porta alla necessità di strumenti per intermediari come i mappatori relazionali di oggetti e simili. Sfortunatamente, mentre questi strumenti hanno chiaramente un posto nel mondo dello sviluppo odierno, il loro uso è semplicemente mirato a un sintomo del problema di complessità dei dati relazionali, piuttosto che alla causa sottostante, che è un disallineamento del modello di dati al mondo reale. p>

Questo porta alla seconda parte della domanda, che era davvero più di una supposizione, ma dovrebbe essere vista come una domanda: dovremmo ottenere il nostro modello di dominio fatto bene la prima volta?

Sì, in una certa misura. Come è stato sottolineato nella domanda, raramente è possibile comprendere appieno il problema quando iniziamo il processo di progettazione. Tuttavia, la differenza tra un modello di dati completamente errato, al contrario di uno che può essere ottimizzato mentre acquisiamo una maggiore comprensione del dominio, è il modello che mappa in modo coerente il mondo reale. Ciò significa che dobbiamo fare ogni sforzo per creare un modello iniziale di dati che sia coerente con la nostra comprensione del problema in termini di entità reali. Se iniziamo a normalizzare su entità sbagliate, il modello di dati sarà sbagliato in due modi e il recupero sarà difficile.

In molti modi, il passaggio alle soluzioni di database "No SQL" è il risultato dei problemi di incoerenza del modello di dati. L'utilizzo di un approccio No SQL orientato agli oggetti ci induce a pensare di più alla mappatura tra i nostri oggetti nel codice e quelli nel mondo reale- e quando ci imbattiamo in un'incoerenza, spesso è evidente perché non è fattibile implementare nel nostro Banca dati. Ciò porta a una migliore progettazione generale.

Questo porta alla domanda finale: è un modello di dati relazionali incoerente con l'approccio agile?

No, ma sono richieste più abilità. Mentre nel mondo No-SQL, è banale aggiungere un campo o convertire una proprietà in un array, non è affatto banale fai queste cose nel mondo relazionale. Prende, come minimo, qualcuno che sia in grado di comprendere sia il modello di dati relazionale che le entità del mondo reale che rappresentano. Questa persona è l'individuo che faciliterà l'aggiornamento del modello relazionale come la comprensione dei cambiamenti del modello del mondo reale. Non esiste un proiettile d'argento per risolvere questo problema.

    
risposta data 22.02.2016 - 18:50
fonte
-1

Il punto principale non è quello di refactoring tanto che il modello cambia oltre ogni riconoscimento. Anche con lo sviluppo iterativo dovresti davvero costruire sulla base delle cose esistenti e non ridurla a pezzi.

Questo ti dà 2 opzioni principali per gestire grandi cambiamenti quando arrivano: il primo è quello di costruire il livello DB come API, utilizzare le stored procedure in modo che possano essere modificate per adattarsi al client senza modificare lo schema dei dati sottostanti.

L'altro modo è sostituire le tabelle con un po 'di migrazione dei dati. Quando è necessario un cambiamento su larga scala, si crea il nuovo schema e si implementa una serie di script per prendere i vecchi dati e massaggiarli nel nuovo formato. È il momento di farlo, motivo per cui ci si affida maggiormente a metodi meno costosi di modifica dell'accesso ai dati (ad esempio tramite SP) come prima scelta.

Quindi: 1. prova a pensare al design in modo da non dover cambiare le cose.

  1. Fai affidamento su wrapper o API in modo che le modifiche siano limitate o possano essere nascoste all'interno di un componente isolato

  2. Prenditi del tempo per eseguire l'aggiornamento correttamente se necessario.

Questi passaggi si applicano a tutto, non solo ai database.

    
risposta data 22.02.2016 - 11:07
fonte