Domanda

Questa sembra essere un'area trascurata che potrebbe davvero essere utile per qualche intuizione.Quali sono le migliori pratiche per:

  • effettuare una procedura di aggiornamento
  • ritirarsi in caso di errori
  • sincronizzare le modifiche al codice e al database
  • test prima della distribuzione
  • meccanica di modifica della tabella

eccetera...

È stato utile?

Soluzione

Questa è una bella domanda.(C'è un'alta probabilità che questo finisca con un dibattito sul database normalizzato o denormalizzato... che non inizierò...ok, ora qualche input.)

alcune cose che non avevo in mente e che ho fatto (ne aggiungerò altre quando avrò più tempo o avrò bisogno di una pausa)

progettazione client: è qui che il metodo VB di SQL inline (anche con istruzioni preparate) ti mette nei guai.Puoi spendere ETÀ solo per trovare quelle affermazioni.Se usi qualcosa come Hibernate e inserisci tanto SQL nelle query con nome, hai un unico posto per la maggior parte di SQL (niente di peggio che provare a testare SQL che si trova all'interno di alcune istruzioni IF e semplicemente non premi il "trigger" criteri nel test per quella dichiarazione IF).Prima di utilizzare l'ibernazione (o altri formati) quando eseguivo SQL direttamente in JDBC o ODBC, inserirei tutte le istruzioni SQL come campi pubblici di un oggetto (con una convenzione di denominazione) o in un file di proprietà (anch'esso con una denominazione la convenzione per i valori dice PREP_STMT_xxxx.E usa la riflessione o l'iterazione sui valori all'avvio in a) casi di test b) avvio dell'applicazione (alcuni rdbms ti consentono di precompilare con istruzioni preparate prima dell'esecuzione, quindi all'avvio dopo l'accesso vorrei precompilare la preparazione stmts all'avvio per eseguire l'autotest dell'applicazione.Anche per centinaia di affermazioni su un buon rdbms sono solo pochi secondi.e solo una volta.E mi ha salvato molto il sedere.Su un progetto i DBA non comunicavano (un team diverso, in un paese diverso) e lo schema sembrava cambiare NOTTE, senza motivo.E ogni mattina ricevevamo un elenco di dove esattamente si è verificata l'interruzione dell'applicazione, all'avvio.

Se hai bisogno di funzionalità ad hoc, inseriscila in una classe ben denominata (es.ancora una volta una convenzione di denominazione aiuta con i test automatizzati) che agisce come una sorta di factory per la tua query (es.costruisce la query).Dovrai comunque scrivere il codice equivalente, basta metterlo in un posto dove puoi testarlo.Puoi anche scrivere alcuni metodi di test di base sullo stesso oggetto o in una classe separata.

Se puoi, prova anche a utilizzare le procedure memorizzate.Sono un po' più difficili da testare come sopra.Alcuni db inoltre non preconvalidano SQL nei processi memorizzati rispetto allo schema in fase di compilazione solo in fase di esecuzione.Di solito si tratta di prendere una copia della struttura dello schema (nessun dato) e quindi creare tutti i processi memorizzati su questa copia (nel caso in cui il team db che ha apportato le modifiche non sia stato convalidato correttamente).In questo modo è possibile verificare la struttura.ma come punto di gestione del cambiamento i processi memorizzati sono ottimi.Al cambiamento lo capiscono tutti.Soprattutto quando le modifiche al database sono il risultato di cambiamenti nei processi aziendali.E tutte le lingue (Java, vb, ecc. ottengono la modifica)

Di solito imposto anche una tabella che utilizzo chiamata system_setting ecc.In questa tabella manteniamo un identificatore VERSION.In questo modo le librerie client possono connettersi e verificare se sono valide per questa versione dello schema.A seconda delle modifiche al tuo schema, non vuoi consentire ai client di connettersi se possono corrompere il tuo schema (ad es.non hai molte regole referenziali nel db, ma sul client).Dipende se avrai anche più versioni client (cosa che accade nelle app NON Web, ad es.stanno eseguendo il binario sbagliato).Potresti anche avere strumenti batch ecc.Un altro approccio che ho adottato è stato definire un insieme di schemi per le versioni delle operazioni in una sorta di file delle proprietà o ancora in una tabella system_info.Questa tabella viene caricata all'accesso e quindi utilizzata da ciascun "manager" (di solito ho una sorta di API lato client per eseguire la maggior parte delle cose db) per convalidare l'operazione se è la versione giusta.Pertanto la maggior parte delle operazioni può avere successo, ma puoi anche fallire (generare qualche eccezione) su metodi non aggiornati e ti dice PERCHÉ.

gestire la modifica allo schema -> aggiorni la tabella o aggiungi relazioni 1-1 alle nuove tabelle?Per questo motivo ho visto molti negozi che accedono sempre ai dati tramite una vista.Ciò consente di modificare i nomi delle tabelle, delle colonne, ecc.Ho giocato con l'idea di trattare effettivamente le viste come interfacce in COM.cioè.aggiungi una nuova VISTA per nuove funzionalità/versioni.Spesso, ciò che ti porta qui è che puoi avere molti report (in particolare report personalizzati per l'utente finale) che presuppongono formati di tabella.Le visualizzazioni ti consentono di distribuire un nuovo formato di tabella ma supportano le app client esistenti (ricorda tutti quei fastidiosi report ad hoc).

Inoltre, è necessario scrivere script di aggiornamento e rollback.e ancora TEST, TEST, TEST...

------------ OK, QUESTO È UN MOMENTO DI DISCUSSIONE UN PO' CASUALE --------------

In realtà aveva un grande progetto commerciale (es.negozio di software) dove abbiamo avuto lo stesso problema.L'architettura era a 2 livelli e utilizzavano un prodotto un po' simile a PHP ma pre-php.Stessa cosa.nome diverso.comunque sono arrivato nella versione 2....

Costava MOLTI SOLDI fare gli aggiornamenti.Molto.cioè.regala settimane di consulenza gratuita in loco.

E si stava arrivando al punto di voler aggiungere nuove funzionalità o ottimizzare il codice.Parte del codice esistente utilizzava procedure memorizzate, quindi avevamo punti comuni in cui potevamo gestire il codice.ma altre aree erano questo markup SQL incorporato in HTML.Il che è stato ottimo per arrivare rapidamente sul mercato, ma con ogni interazione di nuove funzionalità il costo di test e manutenzione è almeno raddoppiato.Quindi, quando stavamo cercando di estrarre il codice del tipo php, inserendo livelli di dati (questo era 2001-2002, prima di qualsiasi ORM, ecc.) e aggiungendo molte nuove funzionalità (feedback dei clienti), abbiamo esaminato il problema di come progettare gli AGGIORNAMENTI nel sistema.Il che è un grosso problema, poiché gli aggiornamenti costano un sacco di soldi se eseguiti correttamente.Ora, la maggior parte dei pattern e tutte le altre cose di cui le persone discutono con un certo grado di energia hanno a che fare con il codice OO in esecuzione, ma che dire del fatto che i tuoi dati devono a) integrarsi in questa logica, b) il significato e anche la struttura di i dati possono cambiare nel tempo e spesso, a causa del modo in cui funzionano, ci si ritrova con molti processi secondari/applicazioni nell'organizzazione dei clienti che necessitano di tali dati -> reporting ad hoc o qualsiasi reporting personalizzato complesso, nonché lavori batch che sono stati fatti per feed di dati personalizzati ecc.

Con questo in mente ho iniziato a giocare con qualcosa un po' fuori campo.Ha anche alcune ipotesi.a) i dati vengono letti più che scritti.b) gli aggiornamenti avvengono, ma non a livello bancario, ad es.uno o due al secondo diciamo.

L'idea era di applicare una vista COM/Interfaccia al modo in cui i client accedevano ai dati su una serie di tabelle CONCRETE (che variavano con le modifiche dello schema).È possibile creare una vista separata per ogni tipo di operazione: aggiornamento, eliminazione, inserimento e lettura.Questo è importante.Le visualizzazioni verranno mappate direttamente su una tabella o consentiranno di attivare una tabella fittizia che esegue gli aggiornamenti o gli inserimenti reali, ecc.Ciò che in realtà volevo era una sorta di livello indiretto intrappolabile che potesse ancora essere utilizzato dai rapporti di cristallo, ecc.NOTA: per inserimenti, aggiornamenti ed eliminazioni è possibile utilizzare anche le procedure memorizzate.E avevi una versione per ogni versione del prodotto.In questo modo la tua versione 1.0 aveva la sua versione dello schema e, se le tabelle cambiassero, avresti comunque la versione 1.0 VIEWS ma con la NUOVA logica di backend per mappare le nuove tabelle secondo necessità, ma avresti anche le visualizzazioni della versione 2.0 che avrebbero supportato nuovi campi ecc.Questo in realtà era solo per supportare il reporting ad hoc, che se sei una persona BUSINESS e non un programmatore è probabilmente il motivo principale per cui hai il prodotto.(il tuo prodotto può essere scadente ma se hai il miglior reporting al mondo puoi comunque vincere, è vero il contrario: il tuo prodotto può essere la migliore funzionalità in termini di funzionalità, ma se è peggiore nel reporting puoi perdere molto facilmente).

okay, spero che alcune di queste idee siano d'aiuto.

Altri suggerimenti

Liquibase

www.liquibase.org:

  1. comprende le definizioni di ibernazione.
  2. genera un migliore aggiornamento dello schema SQL rispetto all'ibernazione
  3. registra quali aggiornamenti sono stati apportati a un database
  4. gestisce le modifiche in due fasi (ad es.eliminare una colonna "foo" e quindi rinominare un'altra colonna in "foo")
  5. gestisce il concetto di aggiornamenti condizionali
  6. lo sviluppatore ascolta effettivamente la community (con l'ibernazione se non sei tra la folla "in" o un principiante - sei praticamente ignorato.)

http://www.liquibase.org

opinione

l'applicazione dovrebbe Mai gestire un aggiornamento dello schema.Questo è un disastro in attesa di accadere.I dati sopravvivono alle applicazioni e non appena più applicazioni tentano di lavorare con gli stessi dati (ad esempio l'app di produzione + un'app di reporting) è probabile che entrambe utilizzino le stesse librerie aziendali sottostanti...e quindi entrambi i programmi decidono di eseguire il proprio aggiornamento del database ...divertiti con Quello disordine.

Sono un grande fan di Porta Rossa prodotti che aiutano a creare pacchetti SQL per aggiornare gli schemi di database.Gli script del database possono essere aggiunti al controllo del codice sorgente per facilitare il controllo delle versioni e il rollback.

In generale la mia regola è:"L'applicazione dovrebbe gestire il proprio schema."

Ciò significa che gli script di aggiornamento dello schema fanno parte di qualsiasi pacchetto di aggiornamento per l'applicazione e vengono eseguiti automaticamente all'avvio dell'applicazione.In caso di errori l'applicazione non si avvia e la transazione dello script di aggiornamento non viene confermata.Lo svantaggio è che l'applicazione deve avere pieno accesso alle modifiche allo schema (questo infastidisce i DBA).

Ho avuto un grande successo utilizzando la funzionalità SchemaUpdate di Hibernates per gestire le strutture delle tabelle.Lasciare che gli script di aggiornamento gestiscano solo l'inizializzazione effettiva dei dati e la rimozione occasionale di colonne (SchemaUpdate non lo fa).

Per quanto riguarda il test, poiché gli aggiornamenti fanno parte dell'applicazione, testarli diventa parte del ciclo di test dell'applicazione.

Ripensamento:Prendendo in considerazione alcune delle critiche contenute in altri post qui, nota che la regola dice "è propria".Si applica realmente solo dove application possiede lo schema, come generalmente accade con il software venduto come prodotto.Se il tuo software condivide un database con altri software, utilizza altri metodi.

Questi sono tutti argomenti importanti, ma ecco la mia raccomandazione per l'aggiornamento.

Non hai specificato la tua piattaforma, ma per gli ambienti di build NANT che utilizzo Tarantino.Per ogni aggiornamento del database che sei pronto per eseguire il commit, esegui uno script di modifica (utilizzando RedGate o un altro strumento).Quando costruisci in produzione, Tarantino controlla se lo script è stato eseguito sul database (aggiunge una tabella al tuo database per tenerne traccia).In caso contrario, lo script viene eseguito.Ci vuole tutto il lavoro manuale (leggi:errore umano) senza gestire le versioni del database.

Come ha detto Pat, usa liquibase.Soprattutto quando si hanno diversi sviluppatori con i propri database di sviluppo che apportano modifiche che diventeranno parte del database di produzione.

Se c'è un solo sviluppatore, come su un progetto a cui sto lavorando ora (ah), effettuo semplicemente il commit delle modifiche allo schema come file di testo SQL in un repository CVS, che controllo in batch sul server di produzione quando le modifiche al codice vengono apportate .

Ma liquibase è meglio organizzato di così!

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top