Vă mulțumim pentru susținere

Mecanisme pentru urmărirea modificărilor schemei DB

Care sunt cele mai bune metode pentru urmărirea și / sau automatizarea modificărilor schemelor DB? Echipa noastră utilizează Subversion pentru controlul versiunii și am reușit să automatizăm unele dintre sarcinile noastre în acest fel (împingerea se construiește până la un server de staționare, implementând codul testat pe un server de producție), dar facem în continuare actualizări de bază de date manual. Aș dori să găsesc sau să creez o soluție care să ne permită să lucrăm eficient pe servere cu medii diferite, continuând să folosim Subversion ca o backend prin care actualizările de cod și DB sunt împinse către diverse servere.

Multe pachete de software populare includ scripturi de auto-actualizare care detectează versiunea DB și aplică modificările necesare. Este cel mai bun mod de a face acest lucru chiar și la o scară mai largă (în mai multe proiecte și, uneori, în medii și limbi multiple)? Dacă da, există vreun cod existent acolo care simplifică procesul sau este cel mai bine doar să ne rotim propria soluție? A implementat cineva ceva similar înainte și a integrat-o în cârligele post-commitment Subversion sau este o idee rea?

În timp ce o soluție care suportă mai multe platforme ar fi preferabilă, cu siguranță avem nevoie să susținem stiva Linux / Apache / MySQL / PHP, deoarece majoritatea lucrărilor noastre se află pe acea platformă.

0
adăugat editat

19 răspunsuri

Este destul de scăzut de tehnologie și ar putea exista o soluție mai bună acolo, dar puteți să stocați schița într-un script SQL care poate fi rulat pentru a crea baza de date. Cred că puteți executa o comandă pentru a genera acest script, dar din nefericire nu știu comanda.

Apoi, comiteți scriptul în controlul sursă împreună cu codul care funcționează pe acesta. Când trebuie să schimbați schema împreună cu codul, scriptul poate fi verificat împreună cu codul care necesită schema schimbată. Apoi, diffsurile de pe script vor indica diferențe la modificările schemelor.

Cu acest script, îl puteți integra cu DBUnit sau cu un script de construire, deci se pare că se potrivește cu procesele deja automatizate.

0
adăugat
Da, asta e exact ceea ce avem acum. Din păcate, acest lucru nu ne oferă o modalitate ușoară de modificare a bazelor de date existente - scriptul SQL generat de mysqldump presupune că creați tabelul de la zero (sau suprascrieți un tabel dacă există). Avem nevoie de ceva mai mult de înaltă tehnologie, deoarece trebuie să aplicăm o succesiune de instrucțiuni ALTER TABLE în baza de date și, pentru a face acest lucru în mod corespunzător, trebuie să fie conștienți de starea actuală a bazei de date.
adăugat autor pix0r

Dacă utilizați C #, aruncați o privire la Subsonic, un instrument ORM foarte util, dar generează și un script sql pentru a recrea schema și \ sau datele. Aceste scripturi pot fi apoi introduse în controlul sursei.

http://subsonicproject.com/

0
adăugat
Mi se pare bine?
adăugat autor Dan
Se pare că este un URL mort din acest moment.
adăugat autor Mark Schultheiss
doar dragoste subsonic!
adăugat autor TheVillageIdiot

Echipa mea scriptează toate modificările bazei de date și comite aceste scripturi către SVN, împreună cu fiecare lansare a aplicației. Acest lucru permite modificări incrementale ale bazei de date, fără a pierde date.

Pentru a trece de la o versiune la alta, trebuie doar să rulați setul de scripturi de schimbare, iar baza de date este actualizată și tot aveți toate datele. Este posibil să nu fie cea mai ușoară metodă, dar cu siguranță este eficientă.

0
adăugat
cum scrii toate modificările?
adăugat autor Smith

Așezați schema într-un fișier și adăugați-o la controlul sursei. Apoi, o simplă diferență vă va arăta ce sa schimbat.

0
adăugat
Diferența va arăta că o coloană a dispărut, în timp ce cealaltă a apărut (cu excepția cazului în care au același nume) și, de cele mai multe ori, este suficient. Scrierea tuturor schimbărilor schemelor este o modalitate bună de a merge, desigur: în Drupal acest lucru este tratat de un cârlig special, de exemplu.
adăugat autor deadprogrammer
Dump-ul trebuie să fie în SQL, ca un mysqldump, depozitele Oracle sunt binare.
adăugat autor Osama Al-Maadeed
Există, de asemenea, o problemă mai fundamentală cu difuzarea schemei. Cum diferențiați o coloană + adaugă o adăugare dintr-o redenumire de coloană. Răspunsul este simplu: nu puteți. Acesta este motivul pentru care trebuie să înregistrați operațiunile reale de schimbare a schemei.
adăugat autor psp

Folosim o soluție foarte simplă dar eficientă.

Pentru instalările noi, avem un fișier metadata.sql în depozit care conține toate schemele DB, apoi în procesul de construire folosim acest fișier pentru a genera baza de date.

Pentru actualizări, adăugăm actualizările în software-ul hardcoded. Păstrăm codul hardcod, deoarece nu ne place rezolvarea problemelor înainte ca aceasta să fie o problemă și acest lucru nu sa dovedit a fi o problemă până acum.

Deci, în software-ul nostru avem ceva de genul:

ÎnregistrareUpgrade (1, 'ALTER TABLE XX ADD XY CHAR (1) NU NULL;');

Acest cod va verifica dacă baza de date este în versiunea 1 (care este stocată într-o tabelă creată automat), dacă este depășită, atunci comanda este executată.

Pentru a actualiza metadata.sql în repozitoriu, executam aceste actualizări la nivel local și apoi extragem metadatele complete ale bazei de date.

Singurul lucru care se întâmplă atât de des este să uiți să comiți metadata.sql, dar aceasta nu este o problemă majoră, deoarece este ușor de testat procesul de construire și de asemenea singurul lucru care s-ar putea întâmpla este să faceți o instalare nouă cu o bază de date depășită și o modernizată la prima utilizare.

De asemenea, nu acceptăm downgrade-uri, dar este de proiectare, dacă ceva se rupe la o actualizare, am restabilit versiunea anterioară și am repara actualizarea înainte de a încerca din nou.

0
adăugat

Creez foldere numite după versiunile de construire și pun script-uri de upgrade și downgrade acolo. De exemplu, puteți avea următoarele dosare: 1.0.0, 1.0.1 și 1.0.2. Fiecare conține scriptul care vă permite să actualizați sau să vă downgradați baza de date între versiuni.

În cazul în care un client sau un client vă sună cu o problemă cu versiunea 1.0.1 și utilizați 1.0.2, aducerea bazei de date la versiunea sa nu va fi o problemă.

În baza de date, creați un tabel denumit "schemă" unde ați pus în versiunea curentă a bazei de date. Apoi, scrierea unui program care vă poate îmbunătăți sau downgrade baza de date pentru dvs. este ușor.

Ca și cum a spus Joey, dacă vă aflați într-o lume Rails, utilizați Migrații. :)

0
adăugat

Toad pentru MySQL are o funcție numită comparare schemă care vă permite să sincronizați două baze de date. Este cel mai bun instrument pe care l-am folosit până acum.

0
adăugat

Migrațiile IMHO au o mare problemă:

Actualizarea de la o versiune la alta se comporta bine, dar o instalare proaspata a unei versiuni date ar putea dura pentru totdeauna daca aveti sute de mese si o istorie lunga de schimbari (ca si noi).

Executarea întregii istorii a deltaselor de la linia de bază până la versiunea curentă (pentru sute de baze de date ale clienților) ar putea dura foarte mult timp.

0
adăugat

K. Scott Allen are un articol decent sau două despre versiunea schemelor, care folosește conceptul incremental de script-uri / migrații menționat în alte răspunsuri aici; consultați http://odetocode.com/Blogs/scott/archive/ 2008/01/31 / 11710.aspx .

0
adăugat

Folosim ceva similar cu bcwoord pentru a ne sincroniza schemele de baze de date pe 5 instalatii diferite (productie, stadializare si cateva instalatii de dezvoltare) si sustinut in controlul versiunii si functioneaza destul de bine. Voi elabora un pic:


Pentru a sincroniza structura bazei de date, avem un singur script, update.php, și un număr de fișiere numerotate 1.sql, 2.sql, 3.sql, etc. Scriptul folosește un tabel suplimentar pentru a stoca numărul versiunii curente a Bază de date. Fișierele N.sql sunt create manual, pentru a trece de la versiunea (N-1) la versiunea N a bazei de date.

Ele pot fi folosite pentru a adăuga tabele, a adăuga coloane, pentru a migra date dintr-un format vechi într-o coloană nouă, apoi a renunța la coloană, a introduce rânduri de date "master", cum ar fi tipurile de utilizatori etc. În principiu, poate face orice, script-uri de migrare nu veți pierde niciodată date.

Scriptul de actualizare funcționează astfel:

  • Connect to the database.
  • Make a backup of the current database (because stuff will go wrong) [mysqldump].
  • Create bookkeeping table (called _meta) if it doesn't exist.
  • Read current VERSION from _meta table. Assume 0 if not found.
  • For all .sql files numbered higher than VERSION, execute them in order
  • If one of the files produced an error: roll back to the backup
  • Otherwise, update the version in the bookkeeping table to the highest .sql file executed.

Totul merge în controlul sursei, iar fiecare instalare are un script care să se actualizeze la cea mai recentă versiune cu o singură executare de script (apelând update.php cu parola adecvată a bazei de date etc.). SVN actualizează mediile de staționare și producție printr-un script care solicită automat scriptul de actualizare a bazei de date, astfel încât o actualizare de cod vine cu actualizările necesare ale bazei de date.

De asemenea, putem folosi același script pentru a recrea întreaga bază de date de la zero; noi doar picătură și recreează baza de date, apoi rulați script-ul care va repopula complet baza de date. De asemenea, putem folosi scriptul pentru a popula o bază de date goală pentru testarea automată.


A fost nevoie de numai câteva ore pentru a configura acest sistem, este conceptual simplu și toată lumea primește schema de numerotare a versiunilor și a fost de neprețuit în capacitatea de a avansa și de a dezvolta designul bazei de date fără a trebui să comunice sau să execute manual modificările pe toate bazele de date.

Beware when pasting queries from phpMyAdmin though! Those generated queries usually include the database name, which you definitely don't want since it will break your scripts! Something like CREATE TABLE mydb.newtable(...) will fail if the database on the system is not called mydb. We created a pre-comment SVN hook that will disallow .sql files containing the mydb string, which is a sure sign that someone copy/pasted from phpMyAdmin without proper checking.

0
adăugat
Cum ai manevrat coliziunile? Dezvoltatorii multipli care modifică același element în DB, de exemplu o procedură stocată? Acest lucru se poate întâmpla dacă lucrați la aceeași ramură sau aveți două linii de dezvoltare (două sucursale)
adăugat autor Asaf Mesika
Coliziuni au fost foarte rare; singurul lucru care sa întâmplat într-adevăr este că doi oameni ar încerca să creeze același fișier N.sql. Desigur, primul câștigă, iar cel de-al doilea este obligat să redenumiți numărul următor și să încercați din nou. Nu am avut versiunea bazei de date pe o ramură, totuși.
adăugat autor rix0rrr

Încercați db-deploy - în principal un instrument Java, dar funcționează și cu php.

0
adăugat

În lumea Rails, există conceptul de migrații, scripturi în care modificările aduse bazei de date sunt făcute în Ruby, mai degrabă decât o aromă specifică bazei de date SQL. Codul dvs. de migrare Ruby se termină prin convertirea în DDL specifică pentru baza dvs. de date curentă; acest lucru face ca platformele bazelor de date de comutare să fie foarte ușoare.

Pentru fiecare modificare efectuată în baza de date, scrieți o nouă migrare. Migrațiile au în mod obișnuit două metode: o metodă "în sus" în care se aplică modificările și o metodă "în jos" în care modificările sunt anulate. O singură comandă aduce actualizarea bazei de date și poate fi folosită și pentru a aduce baza de date la o versiune specifică a schemei. În Rails, migrațiile sunt păstrate în directorul propriu în directorul de proiect și sunt verificate în controlul versiunii ca orice alt cod de proiect.

This Oracle guide to Rails migrations covers migrations quite well.

Dezvoltatorii care folosesc alte limbi s-au uitat la migrații și au implementat propriile versiuni specifice limbii. Știu despre Ruckusing , un sistem de migrare PHP care este modelat după migrațiile lui Rails; ar putea fi ceea ce căutați.

0
adăugat
Acesta este acum situat la adresa github: github.com/ruckus/ruckusing-migrations
adăugat autor xXx
Ruckusing FTW - am adaptat-o ​​la sistemul nostru db și suntem destul de mulțumiți de el.
adăugat autor Piskvor
Mulțumesc că l-ați menționat pe Ruckusing
adăugat autor andho

Am folosit următoarea structură de baze de date în Visual Studio pentru mai multe proiecte și a funcționat destul de bine:

Bază de date

Schimbarea scripturilor

     
    

0.PreDeploy.sql

         

1.SchemaChanges.sql

         

2.DataChanges.sql

         

3.Permissions.sql

  
     

Creați script-uri

     
    

Sprocs

         

Funcții

         

Views

  

Our build system then updates the Bază de date from one version to the next by executing the scripts in the following order:

1.PreDeploy.sql

     

2.SchemaChanges.sql

     

Conținutul directorului Creare scripturi

     

2.DataChanges.sql

     

3.Permissions.sql

Fiecare dezvoltator verifică modificările pentru o anumită eroare / caracteristică prin adăugarea codului lor la sfârșitul fiecărui fișier. Odată ce o versiune majoră este completă și ramificată în controlul sursă, conținutul fișierelor .sql din dosarul Schimbare script-uri este șters.

0
adăugat

Pentru proiectul meu PHP actual folosim ideea de migrații a șinelor și avem un director de migrații în care păstrăm titlul de fișiere "migration_XX.sql" unde XX este numărul migrației. În prezent, aceste fișiere sunt create manual, deoarece sunt făcute actualizări, însă crearea acestora ar putea fi ușor modificată.

Apoi avem un script numit "Migration_watcher" care, așa cum suntem în pre-alfa, rulează în prezent la fiecare încărcare a paginii și verifică dacă există un nou fișier migration_XX.sql unde XX este mai mare decât versiunea curentă de migrare. Dacă este așa, rulează toate fișierele migration_XX.sql până la cel mai mare număr față de baza de date și voila! modificările schemelor sunt automatizate.

Dacă aveți nevoie de capacitatea de a reveni la sistem, ar fi nevoie de o mulțime de tweaking, dar este simplu și a funcționat foarte bine pentru echipa noastră destul de mică până în prezent.

0
adăugat

Scott Ambler produce o mare serie de articole (și a co-autorizat o carte ) despre refactorizarea bazei de date , cu ideea că ar trebui să aplicați în principal principiile și practicile TDD pentru a vă menține schema. Ați creat o serie de teste pentru unitățile de date privind structura și semințele pentru baza de date. Apoi, înainte de a schimba ceva, modificați / scrieți testele pentru a reflecta această schimbare.

Am făcut acest lucru de ceva vreme și se pare că funcționează. Am scris un cod pentru generarea numelui de bază al coloanelor și a tipurilor de date într-o suită de testare a unităților. Putem relua acele teste oricând pentru a verifica dacă baza de date din check-ul SVN se potrivește cu db-ul live pe care rulează aplicația.

După cum se dovedește, dezvoltatorii de asemenea, uneori, tweak lor baza de date sandbox și neglijare pentru a actualiza fișierul de schemă în SVN. Codul depinde apoi de o modificare db care nu a fost verificată. Acest tip de eroare poate fi greu de înțeles, dar suita de testare o va ridica imediat. Acest lucru este deosebit de frumos dacă îl integrezi într-un plan de integrare continuă.

0
adăugat

Aș recomanda să folosiți Ant (platforma încrucișată) pentru partea "scripting" (deoarece poate vorbi practic cu orice db acolo prin jdbc) și Subversion pentru depozitul sursă. Ant vă va permite să "copiați" fișierele locale la fișierele locale, înainte de a efectua modificări. 1. backup schema db existente pentru a fișier prin Ant 2. controlul versiunii la depozitul de subversiune prin Ant 3. trimiteți noi declarații sql la db prin Ant

0
adăugat

Există un instrument mysql-diff care compară schemele bazei de date, unde poate fi schema o bază de date live sau un script SQL pe disc. Este bine pentru cele mai multe sarcini de migrare a schemei.

0
adăugat

Dacă sunteți în căutarea de soluții: vă propunem un instrument numit designer neXtep. Acesta este un mediu de dezvoltare a bazelor de date prin care puteți pune toată baza dvs. de date sub controlul versiunii. Lucrați într-un depozit controlat în versiuni, unde fiecare schimbare poate fi urmărită.

Când trebuie să lansați o actualizare, vă puteți angaja componentele și produsul va genera automat scriptul de upgrade SQL de la versiunea anterioară. Desigur, puteți genera acest SQL din orice 2 versiuni.

Apoi, aveți mai multe opțiuni: puteți lua aceste scripturi și le puteți pune în SVN cu codul aplicației dvs., astfel încât acesta să fie implementat de mecanismul dvs. existent. O altă opțiune este utilizarea mecanismului de livrare al neXtep: scripturile sunt exportate în ceva numit "pachet de livrare" (script-uri SQL + descriptor XML), iar un instalator poate înțelege acest pachet și îl poate implementa pe un server țintă asigurând în același timp o coerență strcuturală, dependență verificați, înregistrați versiunea instalată etc.

The product is GPL and is based on Eclipse so it runs on Linux, Mac and windows. It also support Oracle, Mysql and Postgresql at the moment (DB2 support is on the way). Have a look at the wiki where you will find more detailed information : http://www.nextep-softwares.com/wiki

0
adăugat
Arata interesant. Are interfața de comandă, de asemenea, sau este planificată?
adăugat autor Piskvor

Îmi place modul în care Yii gestionează migrarea bazelor de date. O migrare este în esență un script PHP care implementează CDbMigration . CDbMigration definește o metodă up care conține logica de migrare. Este, de asemenea, posibil să se implementeze o metodă jos pentru a sprijini inversarea migrării. Alternativ, safeUp sau safeDown poate fi folosit pentru a vă asigura că migrarea se face în contextul unei tranzacții.

Instrumentul pentru linia de comandă Yii yiic conține suport pentru crearea și executarea migrărilor. Migrațiile pot fi aplicate sau inversate, fie unul câte unul, fie într-un lot. Crearea unei migrări are drept rezultat un cod pentru o clasă PHP care implementează CDbMigration , numită în mod unic pe baza unei marcări de timp și a unui nume de migrare specificat de utilizator. Toate migrările care au fost aplicate anterior în baza de date sunt stocate într-un tabel de migrare.

Pentru mai multe informații, consultați articolul din manualul Migrarea bazei de date .

0
adăugat