Refactoring o aggiornamento di database per gestire nuove funzionalità


9

Diverse risposte a una domanda sullo schema del database , hanno suggerito una tabella aggiuntiva per normalizzare un database per una funzionalità che non fa parte dei requisiti attuali (una tabella Reparto utente per consentire una relazione molti-a-molti tra dipendenti / utenti e dipartimenti diversi che potrebbero appartiene a.).

Non contro la normalizzazione. Sembra che quando si tratta di progettare un database, c'è una forte spinta a includere funzionalità che sono "sicure" che qualcuno vorrà in futuro. È così difficile aggiungere tabelle / campi al database per soddisfare le caratteristiche che si tende a progettare troppo? Non sarebbero rifattorizzati o aggiornati proprio come il resto dell'app se necessario? Rifare le cose non è mai divertente, ma è possibile spostare i dati da una tabella a una nuova. Non sono sicuro di dove finirà questa linea di pensiero.

Modifica: c'è così tanta avversione a questo, mi chiedo quanti progetti finiscono per non aggiungere una funzionalità che richiede una drastica modifica del database o sono approcci non normalizzati adottati come l'aggiunta di un campo DepartmentID2 invece di una nuova tabella. La necessità di più reparti per un dipendente è un problema di dominio comune. Non ho notato molti schemi di database disseminati di relazioni molti-a-molti.


1
+1 Grazie per avermelo chiesto. Ho imparato molto leggendo le risposte alla mia domanda originale, e anche questo è un filo perspicace.
Jim,

Risposte:


3

C'è un intero libro scritto sul refactoring del database. Proprio come con il refactoring del codice, ci sono modi standard per eseguire il refactoring del database. L'unica differenza è che quando si esegue il refactoring del codice, non è necessario considerare lo stato dell'oggetto / codice, mentre nei database è necessario considerare i dati, perché la perdita di dati non è positiva per gli utenti (o per nessuno, in realtà ).

Puoi leggere di più sul refactoring del database qui .


Questo sito è ciò che ha portato alla domanda in primo luogo;)
JeffO

14

Il refactoring del codice è semplice: basta modificare il codice ed eseguire i test di regressione.

Il refactoring dei database è difficile: devi spostare (una quantità potenzialmente enorme di) dati, assicurarti che nessuno di questi venga eliminato, assicurati che i vincoli siano mantenuti nel nuovo schema. E, se hai requisiti di audit sui dati, devi essere in grado di spiegare perché è organizzato in modo diverso ed essere in grado di abbinare i dati pre-refoctor con i dati post-refattore. Inoltre, nessuno dei tuoi vecchi backup corrisponderà al nuovo schema, che rappresenta un altro rischio.

Roba spaventosa.


I test del database non dovrebbero essere diversi. Tutte le modifiche richiedono un controllo e influiscono sui backup. Quanti dati accumulerai prima di riconoscere questa necessità? Se hai convertito i dati, questa funzionalità sarebbe ancora più ovvia.
JeffO,

8
+1 per @Mathew Flynn. Quanti dati accumulerai prima di riconoscere questa necessità? MILIONI di file. Un altro problema è che molte volte la TUA app non è l'unica cosa che utilizza il database. Il database potrebbe avere molte app che funzionano con esso e potresti non sapere nemmeno che esistono (ad es. App "BI" selvatiche). I cambiamenti negli schemi di database sono spaventosi.
Angelo,

2
A volte miliardi di file
HLGEM,

1
Se hai a che fare con miliardi di file, è meglio sapere come spostarli
JeffO

3

Esiste una linea sottile tra dedicare troppo tempo all'ingegnerizzazione eccessiva e investire un po 'del tuo tempo per aggiungere le funzionalità sufficienti per farti risparmiare una notevole quantità di tempo in futuro.


1
Potresti sostenere questo argomento per un'istanza o due isolate, ma quando i "bit" del tempo si sommano troppo?
JeffO,

Dalla mia esperienza, in realtà è il caso della stragrande maggioranza dei progetti. Ma immagino anche che provenga dall'esperienza ed è altamente soggettivo :) Sarei sorpreso se qualcuno potesse darti una ricetta esatta (da qui la "linea sottile").
0x4B1D,

@Jeff O: Non sarà 'bit'. È necessario un investimento del 10% o del 20% del tempo di sviluppo nell'indurimento, poiché il sistema potrebbe sopravvivere sia al periodo di tempo originariamente previsto sia alla propria occupazione.
rwong,

3

Penso che la teoria sia che se includi una tabella di collegamenti per supportare una relazione da molte a molte tra 2 tabelle, allora anche se nei dati esistono davvero solo relazioni molti-a-uno, tutti scriveranno l'SQL in modo tale che se mai un da molti a molti è tutto supportato "funzionerà".

In pratica, di solito non ho scoperto che questo è vero, ma suppongo che l'SQL sia più vicino a ciò che deve essere per supportare molti a molti di quanto non sarebbe altrimenti.

Ma per arrivare specificamente alla tua domanda, in realtà c'è una buona dose di dolore nel convertire una relazione da 1 a molti a molti a molti. Il motivo è che SQL non è progettato con gli stessi tipi di obiettivi di incapsulamento che gli oggetti sono e la maggior parte delle query utilizza più tabelle a livello di database rispetto alle quali le persone si sentirebbero a proprio agio con la visibilità di un oggetto nel livello aziendale.

Pertanto, una modifica a una relazione da molte a molte avrà un impatto su ogni query che coinvolge le 2 tabelle originali, spesso un effetto a cascata molto più ampio di quello che accadrà sul livello aziendale. Quindi le persone fanno di tutto per evitare che ciò accada.

IMHO questo non sarebbe necessario se avessimo un linguaggio migliore di SQL per specificare l'algebra relazionale. Se fosse possibile costruire una query SQL pezzo per pezzo per oggetti che non necessitavano di visibilità per ogni tabella nella query, ciò non accadrebbe. Cose come LINQ (a SQL o alle Entità) tentano di risolvere questo problema, ma è una soluzione molto complessa e difficile da ottimizzare (e sono stato a gruppi di utenti DBA in cui viene menzionato LINQ e ogni volta cresce un gemito collettivo). Sogno un linguaggio di database universalmente supportato con funzioni di algebra relazionale di prima classe ...

Nel frattempo, sì, puoi fare il refactoring da 1 a molti a molti a molti, ma può essere molto faticoso.


Non trasformerai ogni relazione in un numero uno-a-molti?
JeffO,

@Jeff O - Non sono sicuro di aver capito la tua domanda. In caso di dubbi, modello il numero di molti per evitare le insidie ​​menzionate in varie risposte alla tua domanda originale. Sono diventato un po 'più diffidente dopo aver mantenuto database che in realtà hanno reso quasi tutte le relazioni molte o molte, perché avevano finito per fare cose come la creazione di viste che facevano apparire le relazioni 1 a molti (che, in pratica, lo erano tutti). Quindi hanno avuto il peggio di entrambi i mondi. Non ho mai avuto questo accadere sui miei progetti, ma è là fuori come una storia di ammonimento.
psr

3

Di solito lo spiego in questo modo ai PHB - il codice è le pareti e il tetto, il database è la base.

È possibile spostare le pareti e cambiare il tetto. Cambiare le fondamenta richiede molto di scavare e ricostruire le pareti e il tetto.

Ciò che gli sviluppatori inesperti (e i professori universitari) dicono è "ingegneria eccessiva" è ciò che gli sviluppatori esperti chiamano "prove future". Nonostante ciò che dice la specifica, sai cosa probabilmente cambierà durante l'ALM o dove si verificheranno i problemi di prestazioni, quindi vuoi iniziare con la struttura della tabella.

La distribuzione di script di aggiornamento ai server dei clienti è un progetto non banale e ciascuno dei DBA dei clienti è ovunque tu voglia voler triplicare tutto. Alcune colonne e tabelle extra non sono poi così male.


1

La regola generale è che se una relazione è una a una, ma in futuro può essere da molte a molte, allora farla da molte a molte.

Il dipendente / dipartimento è un classico esempio. Nella maggior parte delle piccole aziende questo è effettivamente un rapporto uno a molti il più delle volte . Tuttavia, c'è quasi sempre una situazione in cui diventa molti a molti: uno dei tuoi ingegneri passa alla gestione, ma è ancora responsabile del supporto di un prodotto che ha sviluppato mentre era in ingegneria o, uno dei tuoi addetti alle vendite si è trasferito a sviluppo del prodotto, ma, poiché ha una stretta relazione con un cliente importante, è ancora capo commesso per quel cliente.

Non costa molto di più se uno a molti viene implementato come molti a molti - ma il refactoring di un database e di un'applicazione per supportare molti a molti è costoso e pieno di difficoltà.


Sono d'accordo che ci sono molti domini maturi (come le risorse umane) in cui il cliente non anticipa la necessità, ma sei consapevole che è destinato a succedere.
JeffO,

0

Esistono due modi per esaminare la progettazione del software (e probabilmente molte altre cose): una vista tattica o una visione strategica. Ognuno ha i suoi vantaggi e svantaggi.

Anche con le modifiche al software OO è ancora una seccatura, non solo la parte di codifica è difficile, ma il processo di promozione di un cambiamento alla produzione in ambienti di denuncia (dato lo stato attuale della tecnologia) è irreale per i grandi sistemi che dovrebbero essere lavorando 24 ore su 24, 7 giorni su 7.

Seguo il mio principio che dice: " Quando possibile, progettare strategicamente artefatti software condivisi " - Questo può sembrare che vada contro il principio YAGNI in qualche modo, tuttavia, questa è la mia opinione. Questo approccio garantisce meno rilavorazioni sul costo della complessità e delle risorse.

Nel tuo caso, le attività necessarie per aggiungere una nuova tabella di giunzione includeranno: progettazione, approvazione del progetto, modifica dello schema, riscrittura di diversi metodi per CRUD per 3 tabelle (ad eccezione di alcune letture), creazione di indici, creazione di GUI per il CRUD per la nuova tabella, per consentire all'utente di selezionare i PK in fase di creazione, aggiornamento della nuova tabella, ecc. Oh, e comunque non dimenticare i test unitari, i test di accettazione dell'utente, i test di sistema e la promozione della produzione.

Se ciò non bastasse, il vero incubo deriva dalla perdita di informazioni. Se non si disponeva della tabella di giunzione per iniziare e si è deciso di acquisire le date in cui si è verificata l'associazione / separazione tra un dipendente e un dipartimento, non sarà possibile popolare automaticamente la data sulla tabella di giunzione. Devi inserirli manualmente (se hai i dati).

Quindi, è meglio prevederlo dall'inizio.


Tutto è meglio prevedere fin dall'inizio.
JeffO,

0

Come ha detto Matthew in precedenza, il refactoring / modifica dei database è spesso più coinvolto rispetto al software in quanto anche la gestione dei dati deve essere presa in considerazione. Esistono tecniche che possono aiutare, ad esempio, ad avere una suite appropriata di test di unità di database, a disaccoppiare le applicazioni client dallo schema di base usando una "API DB" - sprocs / views ecc.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.