Logica de afaceri în baza de date folosind SchemaKeeper

Scopul acestui articol este de a folosi exemplul unei biblioteci pastrator de schema arată instrumente care pot simplifica semnificativ procesul de dezvoltare a bazelor de date în cadrul proiectelor PHP folosind SGBD PostgreSQL.

Informațiile din acest articol vor fi, în primul rând, utile dezvoltatorilor care doresc să profite la maximum de capabilitățile PostgreSQL, dar se confruntă cu probleme de menținere a logicii de business plasate în baza de date.

Acest articol nu va descrie avantajele sau dezavantajele stocării logicii de afaceri într-o bază de date. Se presupune că alegerea a fost deja făcută de către cititor.

Următoarele întrebări vor fi luate în considerare:

  1. În ce formă ar trebui să fie stocată un dump al structurii bazei de date într-un sistem de control al versiunilor (denumit în continuare VCS)
  2. Cum să urmăriți modificările în structura bazei de date după salvarea unui dump
  3. Cum să transferați modificările din structura bazei de date în alte medii fără conflicte și fișiere de migrare uriașe
  4. Cum se organizează procesul de lucru paralel pe un proiect de către mai mulți dezvoltatori
  5. Cum să implementați în siguranță mai multe modificări în structura bazei de date într-un mediu de producție

    SchemaKeeper conceput pentru lucrul cu proceduri stocate scrise în limbaj PL/pgSQL. Testarea cu alte limbi nu a fost efectuată, așa că este posibil ca utilizarea să nu fie la fel de eficientă sau să nu fie posibilă.

Cum se stochează un dump al structurii bazei de date în VCS

bibliotecă pastrator de schema oferă o funcție saveDump, care salvează structura tuturor obiectelor din baza de date ca fișiere text separate. Rezultatul este un director care conține structura bazei de date, împărțit în fișiere grupate care pot fi adăugate cu ușurință la VCS.

Să ne uităm la conversia obiectelor dintr-o bază de date în fișiere folosind câteva exemple:

Tip obiect
Schema
Nume
Cale relativă către fișier

tabel
public
Conturile
./public/tables/accounts.txt

Procedură stocată
public
auth (hash bigint)
./public/functions/auth(int8).sql

idee
rezervare
tarife
./booking/views/tariffs.txt

Conținutul fișierelor este o reprezentare textuală a structurii unui obiect de bază de date specific. De exemplu, pentru procedurile stocate, conținutul fișierului va fi definiția completă a procedurii stocate, începând cu blocul CREATE OR REPLACE FUNCTION.

După cum se poate vedea din tabelul de mai sus, calea către fișier stochează informații despre tipul, schema și numele obiectului. Această abordare facilitează navigarea prin descărcarea și revizuirea codului modificărilor din baza de date.

extensie .sql pentru fișierele cu cod sursă de procedură stocată, aceasta a fost selectată astfel încât IDE-ul să ofere automat instrumente pentru interacțiunea cu baza de date atunci când fișierul este deschis.

Cum să urmăriți modificările în structura bazei de date după salvarea unui dump

Prin salvarea unui dump a structurii bazei de date curente în VCS, avem posibilitatea de a verifica dacă s-au făcut modificări structurii bazei de date după crearea dump-ului. În bibliotecă pastrator de schema pentru a detecta modificări în structura bazei de date, este furnizată o funcție verifyDump, care returnează informații despre diferențe fără efecte secundare.

O modalitate alternativă de verificare este să apelați din nou funcția saveDump, specificând același director și verificați în VCS pentru modificări. Deoarece toate obiectele din baza de date sunt salvate în fișiere separate, VCS va afișa doar obiectele modificate.
Principalul dezavantaj al acestei metode este necesitatea de a suprascrie fișierele pentru a vedea modificările.

Cum să transferați modificările din structura bazei de date în alte medii fără conflicte și fișiere de migrare uriașe

Datorită funcției deployDump Codul sursă al procedurilor stocate poate fi editat exact în același mod ca și codul sursă al aplicației obișnuite. Puteți adăuga/șterge linii noi în codul de procedură stocată și puteți împinge imediat modificări la controlul versiunii sau puteți crea/șterge proceduri stocate prin crearea/ștergerea fișierelor corespunzătoare din directorul de descărcare.

De exemplu, pentru a crea o nouă procedură stocată într-o schemă public doar creați un fișier nou cu extensia .sql în director public/functions, plasați codul sursă al procedurii stocate în acesta, inclusiv blocul CREATE OR REPLACE FUNCTION, apoi apelați funcția deployDump. Modificarea și ștergerea unei proceduri stocate se întâmplă în același mod. Astfel, codul intră atât în ​​VCS, cât și în baza de date în același timp.

Dacă apare o eroare în codul sursă al oricărei proceduri stocate sau o discrepanță între numele fișierului și procedura stocată, atunci deployDump va eșua, afișând textul de eroare. Nepotrivirea procedurilor stocate între dump și baza de date curentă este imposibilă atunci când se utilizează deployDump.

Când creați o nouă procedură stocată, nu este nevoie să introduceți manual numele corect al fișierului. Este suficient ca fișierul să aibă extensia .sql. După apel deployDump textul de eroare va conține numele corect, care poate fi folosit pentru a redenumi fișierul.

deployDump vă permite să modificați parametrii unei funcții sau ai unui tip de returnare fără acțiuni suplimentare, în timp ce cu abordarea clasică ar trebui să
executa mai întâi DROP FUNCTION, și numai atunci CREATE OR REPLACE FUNCTION.

Din păcate, există unele situații în care deployDump nu se poate aplica automat modificările. De exemplu, dacă o funcție de declanșare care este utilizată de cel puțin un declanșator este eliminată. Astfel de situații sunt rezolvate manual folosind fișiere de migrare.

Dacă sunteți responsabil pentru migrarea modificărilor la procedurile stocate pastrator de schema, apoi fișierele de migrare trebuie utilizate pentru a transfera alte modificări ale structurii. De exemplu, o bibliotecă bună pentru lucrul cu migrații este doctrină/migraţii.

Migrațiile trebuie aplicate înainte de lansare deployDump. Acest lucru vă permite să faceți toate modificările structurii și să rezolvați situațiile problematice, astfel încât modificările în procedurile stocate să fie ulterior transferate fără probleme.

Lucrul cu migrațiile va fi descris mai detaliat în secțiunile următoare.

Cum se organizează procesul de lucru paralel pe un proiect de către mai mulți dezvoltatori

Este necesar să se creeze un script pentru inițializarea completă a bazei de date, care va fi lansat de dezvoltator pe mașina sa de lucru, aducând structura bazei de date locale în conformitate cu dump-ul salvat în VCS. Cel mai simplu mod este să împărțiți inițializarea bazei de date locale în 3 pași:

  1. Importați un fișier cu o structură de bază care va fi numită de ex. base.sql
  2. Aplicarea Migrațiilor
  3. apel deployDump

base.sql este punctul de plecare pe deasupra căruia sunt aplicate și executate migrațiile deployDumpcare este base.sql + миграции + deployDump = актуальная структура БД. Puteți crea un astfel de fișier folosind utilitarul pg_dump. Folosit base.sql exclusiv la inițializarea bazei de date de la zero.

Să apelăm scriptul pentru inițializarea completă a bazei de date refresh.sh. Fluxul de lucru ar putea arăta astfel:

  1. Dezvoltatorul se lansează în mediul său refresh.sh și obține structura curentă a bazei de date
  2. Dezvoltatorul începe să lucreze la sarcina în cauză, modificând baza de date locală pentru a răspunde nevoilor noii funcționalități (ALTER TABLE ... ADD COLUMN etc)
  3. După finalizarea sarcinii, dezvoltatorul apelează funcția saveDumpsă comite modificările făcute în baza de date în VCS
  4. Relansarea dezvoltatorului refresh.sh, atunci verifyDumpcare arată acum o listă de modificări de inclus în migrare
  5. Dezvoltatorul transferă toate modificările de structură în fișierul de migrare, rulează din nou refresh.sh и verifyDumpși, dacă migrarea este compilată corect, verifyDump nu va arăta nicio diferență între baza de date locală și dump-ul salvat

Procesul descris mai sus este compatibil cu principiile gitflow. Fiecare ramură din VCS va conține propria sa versiune a dump-ului, iar la îmbinarea ramurilor, dump-urile vor fi îmbinate. În cele mai multe cazuri, nu trebuie luată nicio acțiune suplimentară după o îmbinare, dar dacă s-au făcut modificări în ramuri diferite, de exemplu, la același tabel, poate apărea un conflict.

Să luăm în considerare o situație conflictuală folosind un exemplu: există o ramură dezvolta, din care se ramifică două ramuri: feature1 и feature2, care nu au conflicte cu dezvolta, dar au conflicte între ele. Sarcina este de a îmbina ambele ramuri în dezvolta. În acest caz, este recomandat să îmbinați mai întâi una dintre ramuri în dezvoltași apoi îmbina dezvolta la ramura rămasă, rezolvând conflictele în ramura rămasă și apoi îmbinând ultima ramură în dezvolta. În timpul fazei de soluționare a conflictului, poate fi necesar să reparați fișierul de migrare în ultima ramură, astfel încât să se potrivească cu descărcarea finală, care include rezultatele îmbinărilor.

Cum să implementați în siguranță mai multe modificări în structura bazei de date într-un mediu de producție

Datorită prezenței unui dump a structurii actuale a bazei de date în VCS, devine posibilă verificarea bazei de date de producție pentru conformitatea exactă cu structura necesară. Acest lucru asigură că toate modificările pe care le intenționau dezvoltatorii au fost transferate cu succes în baza de producție.

Ca DDL în PostgreSQL este tranzacționale, se recomandă să respectați următoarea ordine de desfășurare, astfel încât, în cazul unei erori neașteptate, să puteți executa „fără durere” ROLLBACK:

  1. Începeți tranzacția
  2. Efectuați toate migrările într-o tranzacție
  3. În aceeași tranzacție, executați deployDump
  4. Fără a finaliza tranzacția, executați verifyDump. Dacă nu există erori, rulați COMMIT. Dacă există erori, rulați ROLLBACK

Acești pași pot fi integrați cu ușurință în abordările existente ale implementării aplicațiilor, inclusiv fără timpi de nefuncționare.

Concluzie

Datorită metodelor descrise mai sus, este posibil să stoarceți performanța maximă din proiectele „PHP + PostgreSQL”, sacrificând în același timp relativ puțin confortul de dezvoltare în comparație cu implementarea întregii logici de afaceri în codul principal al aplicației. În plus, prelucrarea datelor în PL/pgSQL adesea pare mai transparent și necesită mai puțin cod decât aceeași funcționalitate scrisă în PHP.

Sursa: www.habr.com

Adauga un comentariu