{"id":31385,"date":"2019-10-31T21:40:58","date_gmt":"2019-10-31T18:40:58","guid":{"rendered":"https:\/\/prohoster.info\/blog\/biznes-logika-v-baze-dannyh-pri-pomoshhi-schemakeeper\/"},"modified":"2019-10-31T21:40:58","modified_gmt":"2019-10-31T18:40:58","slug":"biznes-logika-v-baze-dannyh-pri-pomoshhi-schemakeeper","status":"publish","type":"post","link":"https:\/\/prohoster.info\/sq\/blog\/administrirovanie\/biznes-logika-v-baze-dannyh-pri-pomoshhi-schemakeeper","title":{"rendered":"Logjika e biznesit n\u00eb baz\u00ebn e t\u00eb dh\u00ebnave p\u00ebrmes SchemaKeeper","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Q\u00ebllimi i k\u00ebtij artikulli \u00ebsht\u00eb t\u00eb tregoj\u00eb, p\u00ebrmes bibliotek\u00ebs <noindex><a rel=\"nofollow\" href=\"https:\/\/packagist.org\/packages\/schema-keeper\/schema-keeper\">schema-keeper<\/a><\/noindex> mjetet q\u00eb leht\u00ebsojn\u00eb ndjesh\u00ebm procesin e zhvillimit t\u00eb bazave t\u00eb t\u00eb dh\u00ebnave n\u00eb projektet PHP q\u00eb p\u00ebrdorin DBMS PostgreSQL.<\/p>\n<p><\/p>\n<p>Informacioni n\u00eb k\u00ebt\u00eb artikull do t\u00eb jet\u00eb sidomos i dobish\u00ebm p\u00ebr zhvilluesit q\u00eb d\u00ebshirojn\u00eb t\u00eb shfryt\u00ebzojn\u00eb sa m\u00eb shum\u00eb mund\u00ebsit\u00eb e PostgreSQL, por hasin v\u00ebshtir\u00ebsi n\u00eb mb\u00ebshtetje t\u00eb logjik\u00ebs s\u00eb biznesit t\u00eb outsourcuara n\u00eb DB. <\/p>\n<p><\/p>\n<p>Artikulli nuk do t\u00eb p\u00ebrshkruaj\u00eb p\u00ebrpar\u00ebsit\u00eb ose disavantazhet e ruajtjes s\u00eb logjik\u00ebs s\u00eb biznesit n\u00eb baz\u00ebn e t\u00eb dh\u00ebnave. Supozohet se zgjedhja \u00ebsht\u00eb b\u00ebr\u00eb nga lexuesi.<\/p>\n<p><\/p>\n<p>Do t\u00eb shqyrtohen pyetje t\u00eb tilla si:<\/p>\n<p><\/p>\n<ol>\n<li>N\u00eb cil\u00ebn form\u00eb t\u00eb ruhet dumpsi i struktur\u00ebs s\u00eb DB n\u00eb sistemin e kontrollit t\u00eb versioneve (VCS)<\/li>\n<li>Si t\u00eb ndjekim ndryshimet n\u00eb struktur\u00ebn e DB pas ruajtjes s\u00eb dumpsit<\/li>\n<li>Si t\u00eb transferojm\u00eb ndryshimet n\u00eb struktur\u00ebn e DB n\u00eb mjedise t\u00eb tjera pa konflikte dhe skedar\u00eb migracionesh gjigande<\/li>\n<li>Si t\u00eb organizojm\u00eb procesin e pun\u00ebs paralele mbi projektin me disa zhvillues<\/li>\n<li>Si t\u00eb deployohet n\u00eb siguri nj\u00eb num\u00ebr t\u00eb madh ndryshimesh n\u00eb struktur\u00ebn e DB n\u00eb ambientin production<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><br \/>\n<blockquote><p><strong>SchemaKeeper<\/strong> \u00ebsht\u00eb i optimizuar p\u00ebr pun\u00eb me procedurat e ruajtura t\u00eb shkruara n\u00eb gjuh\u00ebn <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/current\/plpgsql.html\">PL\/pgSQL<\/a><\/noindex>. Testimi me gjuh\u00eb t\u00eb tjera nuk \u00ebsht\u00eb kryer, p\u00ebr pasoj\u00eb p\u00ebrdorimi mund t\u00eb mos jet\u00eb kaq efektiv, ose t\u00eb jet\u00eb i pamundur.\n<\/p><\/blockquote>\n<\/li>\n<\/ol>\n<p><\/p>\n<h2 id=\"v-kakom-vide-hranit-damp-struktury-bd-v-vcs\">N\u00eb cil\u00ebn form\u00eb t\u00eb ruhet dumpsi i struktur\u00ebs s\u00eb DB n\u00eb VCS<\/h2>\n<p><\/p>\n<p>Biblioteka <noindex><a rel=\"nofollow\" href=\"https:\/\/packagist.org\/packages\/schema-keeper\/schema-keeper\">schema-keeper<\/a><\/noindex> ofron funksionin <code>saveDump<\/code>, i cili ruan struktur\u00ebn e t\u00eb gjith\u00eb objekteve nga DB si skedar\u00eb t\u00eb ve\u00e7ant\u00eb tekstual\u00eb. N\u00eb p\u00ebrfundim krijohet nj\u00eb direktorium q\u00eb p\u00ebrmban struktur\u00ebn e DB, e cila \u00ebsht\u00eb e ndar\u00eb n\u00eb skedar\u00eb t\u00eb grupuar q\u00eb leht\u00eb mund t\u00eb shtohen n\u00eb VCS.<\/p>\n<p><\/p>\n<p>Le t\u00eb shqyrtojm\u00eb transformimin e objekteve nga DB n\u00eb skedar\u00eb p\u00ebrmes disa shembujsh:<\/p>\n<p><\/p>\n<p>Tipi i objektit<br \/>\nSkema<br \/>\nEmri<br \/>\nRruga e relatshme drejt skedarit<\/p>\n<p>Tavolina<br \/>\npublic<br \/>\naccounts<br \/>\n<code>.\/public\/tables\/accounts.txt<\/code><\/p>\n<p>Procedura e ruajtur<br \/>\npublic<br \/>\nauth(hash bigint)<br \/>\n<code>.\/public\/functions\/auth(int8).sql<\/code><\/p>\n<p>P\u00ebrfaq\u00ebsimi<br \/>\nbooking<br \/>\ntariffs<br \/>\n<code>.\/booking\/views\/tariffs.txt<\/code><\/p>\n<p><\/p>\n<p>P\u00ebrmbajtja e skedar\u00ebve \u00ebsht\u00eb nj\u00eb p\u00ebrfaq\u00ebsim t\u00eb tekstit t\u00eb struktur\u00ebs s\u00eb objektit t\u00eb caktuar t\u00eb DB. P\u00ebr shembull, p\u00ebr procedurat e ruajtura, p\u00ebrmbajtja e skedarit do t\u00eb jet\u00eb definicioni i plot\u00eb i procedur\u00ebs s\u00eb ruajtur, q\u00eb fillon me bllokun <code>CREATE OR REPLACE FUNCTION<\/code>.<\/p>\n<p><\/p>\n<p>Si\u00e7 shihet nga tabela e m\u00ebsip\u00ebrme, rruga e skedarit mban informacionin p\u00ebr tipin, skem\u00ebn dhe emrin e objektit. Kjo qasje leht\u00ebson navigimin n\u00eb dumps dhe shqyrtimin e ndryshimeve n\u00eb DB.<\/p>\n<p><\/p>\n<blockquote><p>Zgjerim <code>.sql<\/code> p\u00ebr skedar\u00ebt me kodin burimor t\u00eb procedurave t\u00eb ruajtura, \u00ebsht\u00eb zgjedhur q\u00eb IDE t\u00eb ofrojn\u00eb automatikisht mjete p\u00ebr nd\u00ebrveprimin me Baza t\u00eb Dh\u00ebnash kur hapet skedari.<\/p><\/blockquote>\n<p><\/p>\n<h2 id=\"kak-otslezhivat-izmeneniya-v-strukture-bd-posle-sohraneniya-dampa\">Si t\u00eb ndjekim ndryshimet n\u00eb struktur\u00ebn e DB pas ruajtjes s\u00eb dumpsit<\/h2>\n<p><\/p>\n<p>Duke ruajtur dump-in e struktur\u00ebs aktuale t\u00eb Baza t\u00eb Dh\u00ebnash n\u00eb VCS, ne marrim mund\u00ebsin\u00eb p\u00ebr t\u00eb verifikuar n\u00ebse jan\u00eb b\u00ebr\u00eb ndryshime n\u00eb struktur\u00ebn e baz\u00ebs pas krijimit t\u00eb dump-it. N\u00eb bibliotek\u00ebn <noindex><a rel=\"nofollow\" href=\"https:\/\/packagist.org\/packages\/schema-keeper\/schema-keeper\">schema-keeper<\/a><\/noindex> p\u00ebr identifikimin e ndryshimeve n\u00eb struktur\u00ebn e Baza t\u00eb Dh\u00ebnash \u00ebsht\u00eb parashikuar funksioni <code>verifyDump<\/code>, i cili pa efekte an\u00ebsore kthen informacion mbi ndryshimet. <\/p>\n<p><\/p>\n<p>Nj\u00eb m\u00ebnyr\u00eb alternative verifikimi \u00ebsht\u00eb t\u00eb th\u00ebrras\u00ebsh p\u00ebrs\u00ebri funksionin <code>saveDump<\/code>, duke treguar t\u00eb nj\u00ebjt\u00ebn drejtorin\u00eb, dhe t\u00eb kontrollosh n\u00eb VCS p\u00ebr ndryshime. Ngjash\u00ebm me q\u00eb t\u00eb gjitha objektet nga Baza t\u00eb Dh\u00ebnash jan\u00eb ruajtur n\u00eb skedar\u00eb t\u00eb ve\u00e7ant\u00eb, VCS do t\u00eb tregoj\u00eb vet\u00ebm objektet e ndryshuara.<br \/>\nDisavantazhi kryesor i k\u00ebsaj metode \u00ebsht\u00eb se duhet t\u00eb ri-shkruhen skedar\u00ebt p\u00ebr t\u00eb par\u00eb ndryshimet.<\/p>\n<p><\/p>\n<h2 id=\"kak-perenosit-izmeneniya-v-strukture-bd-na-drugie-okruzheniya-bez-konfliktov-i-gigantskih-faylov-migraciy\">Si t\u00eb transferojm\u00eb ndryshimet n\u00eb struktur\u00ebn e DB n\u00eb mjedise t\u00eb tjera pa konflikte dhe skedar\u00eb migracionesh gjigande<\/h2>\n<p><\/p>\n<p>Fal\u00eb funksionit <code>deployDump<\/code> kodi burimor i procedurave t\u00eb ruajtura mund t\u00eb redaktohet n\u00eb m\u00ebnyr\u00eb t\u00eb nj\u00ebjt\u00eb si\u00e7 b\u00ebhet me kodin e zakonsh\u00ebm t\u00eb aplikacionit. Mund t\u00eb shtohen\/faqen rreshta t\u00eb rinj n\u00eb kodin e procedurave t\u00eb ruajtura dhe menj\u00ebher\u00eb t\u00eb d\u00ebrgohen ndryshimet n\u00eb sistemin e kontrollit t\u00eb versioneve, ose t\u00eb krijohen\/fshihen procedurat e ruajtura duke krijuar\/fshir\u00eb skedar\u00ebt p\u00ebrkat\u00ebs n\u00eb drejtorin\u00eb e dump-it. <\/p>\n<p><\/p>\n<p>P\u00ebr shembull, p\u00ebr t\u00eb krijuar nj\u00eb procedur\u00eb t\u00eb re t\u00eb ruajtur n\u00eb skem\u00ebn <code>public<\/code> mjafton t\u00eb krijosh nj\u00eb skedar t\u00eb ri me shtes\u00ebn <code>.sql<\/code> n\u00eb drejtorin\u00eb <code>public\/functions<\/code>, t\u00eb vendos\u00ebsh n\u00eb t\u00eb kodin burimor t\u00eb procedur\u00ebs s\u00eb ruajtur, duke p\u00ebrfshir\u00eb blokun <code>CREATE OR REPLACE FUNCTION<\/code>, pastaj t\u00eb th\u00ebrras\u00ebsh funksionin <code>deployDump<\/code>. N\u00eb m\u00ebnyr\u00eb t\u00eb ngjashme ndodh ndryshimi dhe fshirja e procedur\u00ebs s\u00eb ruajtur. N\u00eb k\u00ebt\u00eb m\u00ebnyr\u00eb, kodi p\u00ebrfshihet nj\u00ebkoh\u00ebsisht n\u00eb VCS dhe n\u00eb Baza t\u00eb Dh\u00ebnash. <\/p>\n<p><\/p>\n<p>N\u00ebse n\u00eb kodin burimor t\u00eb ndonj\u00eb procedure t\u00eb ruajtur ndodh nj\u00eb gabim, ose nj\u00eb moskonsistenc\u00eb mes emrave t\u00eb skedar\u00ebve dhe procedur\u00ebs s\u00eb ruajtur, at\u00ebher\u00eb <code>deployDump<\/code> nuk do t\u00eb kryhet, duke treguar tekstin e gabimit. Moskonsistenca e procedurave t\u00eb ruajtura mes dump-it dhe Baza t\u00eb Dh\u00ebnash aktuale \u00ebsht\u00eb e pamundur kur p\u00ebrdoret <code>deployDump<\/code>.<\/p>\n<p><\/p>\n<blockquote><p>Kur krijohet nj\u00eb procedur\u00eb e re e ruajtur, nuk \u00ebsht\u00eb e nevojshme t\u00eb shkruhet dorazi emri i sakt\u00eb i skedarit. Mjafton q\u00eb skedari t\u00eb ket\u00eb shtes\u00ebn <code>.sql<\/code>. Pas thirrjes <code>deployDump<\/code> teksti i gabimit do t\u00eb p\u00ebrmbaj\u00eb emrin e sakt\u00eb, i cili mund t\u00eb p\u00ebrdoret p\u00ebr t\u00eb riem\u00ebruar skedarin.<\/p><\/blockquote>\n<p><code>deployDump<\/code> lejon ndryshimin e parametrave t\u00eb funksionit ose llojit t\u00eb kthyer pa veprime t\u00eb tjera, nd\u00ebrsa sipas qasjes klasike do t\u00eb duhej<br \/>\nfillimisht t\u00eb ekzekutonte <code>DROP FUNCTION<\/code>, dhe vet\u00ebm pastaj <code>CREATE OR REPLACE FUNCTION<\/code>.<\/p>\n<p><\/p>\n<p>Fatkeq, ekzistojn\u00eb disa situata kur <code>deployDump<\/code> nuk \u00ebsht\u00eb e mundur t\u00eb aplikohet automatikisht ndryshimet. P\u00ebr shembull, n\u00ebse hiqet nj\u00eb funksion aktivizues q\u00eb p\u00ebrdoret nga t\u00eb pakt\u00ebn nj\u00eb aktivizues. K\u00ebto situata zgjidhen manualisht p\u00ebrmes skedave t\u00eb migrimeve.<\/p>\n<p><\/p>\n<p>N\u00ebse transferimin e ndryshimeve n\u00eb procedurat e ruajtura e b\u00ebn vet\u00eb <noindex><a rel=\"nofollow\" href=\"https:\/\/packagist.org\/packages\/schema-keeper\/schema-keeper\">schema-keeper<\/a><\/noindex>, at\u00ebher\u00eb p\u00ebr t\u00eb transferuar ndryshimet e tjera n\u00eb struktur\u00eb \u00ebsht\u00eb e nevojshme t\u00eb p\u00ebrdoren skedat e migrimeve. P\u00ebr shembull, nj\u00eb bibliotek\u00eb e mir\u00eb p\u00ebr pun\u00ebn me migrimet \u00ebsht\u00eb <noindex><a rel=\"nofollow\" href=\"https:\/\/packagist.org\/packages\/doctrine\/migrations\">doctrine\/migrations<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p>Migrimet duhet t\u00eb aplikohen para se t\u00eb filloj\u00eb <code>deployDump<\/code>. Kjo lejon q\u00eb t\u00eb b\u00ebhen t\u00eb gjitha ndryshimet n\u00eb struktur\u00eb dhe t\u00eb zgjidhen situatat problematike q\u00eb t\u00eb transferohen pa probleme ndryshimet n\u00eb procedurat e ruajtura m\u00eb von\u00eb.<\/p>\n<p><\/p>\n<p>M\u00eb shum\u00eb n\u00eb detaje, puna me migrimet do t\u00eb p\u00ebrshkruhet n\u00eb seksionet n\u00eb vazhdim.<\/p>\n<p><\/p>\n<h2 id=\"kak-naladit-process-parallelnoy-raboty-nad-proektom-neskolkih-razrabotchikov\">Si t\u00eb organizojm\u00eb procesin e pun\u00ebs paralele mbi projektin me disa zhvillues<\/h2>\n<p><\/p>\n<p>\u00cbsht\u00eb e nevojshme t\u00eb krijohet nj\u00eb skenar i plot\u00eb i inicializimit t\u00eb DB-s\u00eb, i cili do t\u00eb ekzekutohet nga zhvilluesi n\u00eb makin\u00ebn e tij t\u00eb pun\u00ebs, duke e sjell\u00eb struktur\u00ebn e DB-s\u00eb lokale n\u00eb p\u00ebrputhje me dump-in e ruajtur n\u00eb VCS. M\u00eb leht\u00eb \u00ebsht\u00eb t\u00eb ndahet inicializimi i DB-s\u00eb lokale n\u00eb 3 hapa:<\/p>\n<p><\/p>\n<ol>\n<li>Importimi i skedarit me struktur\u00ebn baz\u00eb, i cili do t\u00eb quhet, p\u00ebr shembull, <code>base.sql<\/code> <\/li>\n<li>Kthimi i migrimeve<\/li>\n<li>Thirrja <code>deployDump<\/code><\/li>\n<\/ol>\n<p><\/p>\n<blockquote><p><code>base.sql<\/code> \u2014 kjo \u00ebsht\u00eb pika e nisjes, mbi t\u00eb cil\u00ebn aplikohen migrimet dhe ekzekutohet <code>deployDump<\/code>, q\u00eb do t\u00eb thot\u00eb <code>base.sql + migrimet + deployDump = struktura aktuale e DB-s\u00eb<\/code>. Nj\u00eb skedar t\u00eb till\u00eb mund t\u00eb formohet p\u00ebrmes utilitarit <code>pg_dump<\/code>. P\u00ebrdoret <code>base.sql<\/code> p\u00ebr vet\u00eb inicializimin e baz\u00ebs s\u00eb t\u00eb dh\u00ebnave nga fillimi.<\/p><\/blockquote>\n<p>Ta quajm\u00eb skenarin e plot\u00eb t\u00eb inicializimit t\u00eb DB-s\u00eb <code>refresh.sh<\/code>. Procesi i pun\u00ebs mund t\u00eb duket si m\u00eb posht\u00eb:<\/p>\n<p><\/p>\n<ol>\n<li>Zhvilluesi ekzekuton n\u00eb mjedisin e tij <code>refresh.sh<\/code> dhe merr struktur\u00ebn aktuale t\u00eb DB-s\u00eb<\/li>\n<li>Zhvilluesi fillon t\u00eb punoj\u00eb mbi detyr\u00ebn e caktuar, duke modifikuar DB-n\u00eb lokale sipas nevojave t\u00eb funksionalitetit t\u00eb ri (<code>ALTER TABLE ... ADD COLUMN<\/code> etj)<\/li>\n<li>Pas p\u00ebrfundimit t\u00eb detyr\u00ebs, zhvilluesi th\u00ebrret funksionin <code>saveDump<\/code>, p\u00ebr t\u00eb regjistruar n\u00eb VCS ndryshimet e b\u00ebra n\u00eb DB<\/li>\n<li>Zhvilluesi ekzekuton s\u00ebrish <code>refresh.sh<\/code>, pastaj <code>verifyDump<\/code>, i cili tani tregon list\u00ebn e ndryshimeve p\u00ebr t'u p\u00ebrfshir\u00eb n\u00eb migrim<\/li>\n<li>Zhvilluesi transferon t\u00eb gjitha ndryshimet n\u00eb struktur\u00eb n\u00eb skedarin e migrimit, ekzekuton p\u00ebrs\u00ebri <code>refresh.sh<\/code> dhe <code>verifyDump<\/code>, dhe, n\u00ebse migrimi \u00ebsht\u00eb p\u00ebrgatitur sakt\u00eb, <code>verifyDump<\/code> do t\u00eb tregoj\u00eb se nuk ka dallime midis DB-s\u00eb lokale dhe dump-it t\u00eb ruajtur.<\/li>\n<\/ol>\n<p><\/p>\n<p>Procesi t\u00eb p\u00ebrshkruar m\u00eb sip\u00ebr \u00ebsht\u00eb p\u00ebrputhsh\u00ebm me parimet e gitflow. \u00c7do deg\u00eb n\u00eb VCS do t\u00eb p\u00ebrmbaj\u00eb versionin e vet t\u00eb dump-it, dhe kur deg\u00ebt bashkohen, do t\u00eb ndodh\u00eb bashkimi i dump-\u00ebve. N\u00eb shumic\u00ebn e rasteve, pas bashkimit nuk nevojitet t\u00eb merren masa t\u00eb tjera, por n\u00ebse jan\u00eb b\u00ebr\u00eb ndryshime n\u00eb deg\u00eb t\u00eb ndryshme, p\u00ebr shembull, n\u00eb t\u00eb nj\u00ebjt\u00ebn tabel\u00eb, mund t\u00eb ndodhi nj\u00eb konflikt.<\/p>\n<p><\/p>\n<p>Le t\u00eb shqyrtojm\u00eb nj\u00eb situat\u00eb konflikti me shembuj: ka nj\u00eb deg\u00eb <em>develop<\/em>, nga e cila jan\u00eb ndar\u00eb dy deg\u00eb: <em>feature1<\/em> dhe <em>feature2<\/em>, t\u00eb cilat nuk kan\u00eb konflikte me <em>develop<\/em>, por kan\u00eb konflikte midis tyre. Detyra \u00ebsht\u00eb t\u00eb b\u00ebhet bashkimi i t\u00eb dyve deg\u00eb n\u00eb <em>develop<\/em>. N\u00eb k\u00ebt\u00eb rast, rekomandohet s\u00eb pari t\u00eb b\u00ebhet bashkimi i nj\u00ebrit prej deg\u00ebve n\u00eb <em>develop<\/em>, e m\u00eb pas bashkimi <em>develop<\/em> n\u00eb deg\u00ebn tjet\u00ebr, duke zgjidhur konflikte n\u00eb deg\u00ebn e mbetur, dhe m\u00eb pas t\u00eb b\u00ebhet bashkimi i deg\u00ebs s\u00eb fundit n\u00eb <em>develop<\/em>. N\u00eb faz\u00ebn e zgjidhjes s\u00eb konflikteve, mund t\u00eb jet\u00eb e nevojshme t\u00eb korrigjohet skedari i migrimit n\u00eb deg\u00ebn e fundit, n\u00eb m\u00ebnyr\u00eb q\u00eb t\u00eb p\u00ebrputhej me dump-in p\u00ebrfundimtar, i cili p\u00ebrfshin rezultatet e bashkimeve.<\/p>\n<p><\/p>\n<h2 id=\"kak-bezopasno-deploit-bolshee-kolichestvo-izmeneniy-v-strukture-bd-na-production-okruzhenie\">Si t\u00eb deployohet n\u00eb siguri nj\u00eb num\u00ebr t\u00eb madh ndryshimesh n\u00eb struktur\u00ebn e DB n\u00eb ambientin production<\/h2>\n<p><\/p>\n<p>Duke pasur n\u00eb VCS dump-in e struktur\u00ebs aktuale t\u00eb DB-s\u00eb, krijohet mund\u00ebsia p\u00ebr t\u00eb verifikuar baz\u00ebn e t\u00eb dh\u00ebnave n\u00eb prodhim p\u00ebr p\u00ebrputhshm\u00ebrin\u00eb e sakt\u00eb me struktur\u00ebn e k\u00ebrkuar. Kjo garanton q\u00eb t\u00eb gjitha ndryshimet, q\u00eb kishin parashikuar zhvilluesit, jan\u00eb transferuar me sukses n\u00eb baz\u00ebn e t\u00eb dh\u00ebnave n\u00eb prodhim.<\/p>\n<p><\/p>\n<p>Meqen\u00ebse <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/current\/ddl.html\">DDL<\/a><\/noindex> n\u00eb PostgreSQL \u00ebsht\u00eb <noindex><a rel=\"nofollow\" href=\"https:\/\/wiki.postgresql.org\/wiki\/Transactional_DDL_in_PostgreSQL:_A_Competitive_Analysis\">transaksional<\/a><\/noindex>, rekomandohet q\u00eb t\u00eb ndiqet rendi i m\u00ebposht\u00ebm i depot, n\u00eb m\u00ebnyr\u00eb q\u00eb, n\u00eb rast t\u00eb nj\u00eb gabimi t\u00eb papritur, t\u00eb mund t\u00eb b\u00ebhet nj\u00eb <code>ROLLBACK<\/code>:<\/p>\n<p><\/p>\n<ol>\n<li>T\u00eb filloj\u00eb transaksionin<\/li>\n<li>T\u00eb b\u00ebhen t\u00eb gjitha migrimet n\u00eb transaksion<\/li>\n<li>N\u00eb k\u00ebt\u00eb transaksion t\u00eb b\u00ebhet <code>deployDump<\/code><\/li>\n<li>Pa p\u00ebrfunduar transaksionin, t\u00eb b\u00ebhet <code>verifyDump<\/code>. N\u00ebse nuk ka gabime, t\u00eb b\u00ebhet <code>KREJT<\/code>. N\u00ebse ka gabime, t\u00eb b\u00ebhet <code>ROLLBACK<\/code><\/li>\n<\/ol>\n<p><\/p>\n<p>K\u00ebto hapat jan\u00eb mjaft t\u00eb lehta p\u00ebr t'u integruar n\u00eb qasjet ekzistente p\u00ebr depolimin e aplikacioneve, p\u00ebrfshir\u00eb zero-downtime.<\/p>\n<p><\/p>\n<h1 id=\"zaklyuchenie\">P\u00ebrfundim<\/h1>\n<p><\/p>\n<p>Fal\u00eb metodave t\u00eb p\u00ebrshkruara m\u00eb sip\u00ebr, \u00ebsht\u00eb e mundur t\u00eb nxjerrim maksimumin e performanc\u00ebs nga projektet \"PHP + PostgreSQL\", duke sakrifikuar nj\u00eb sasi relativisht t\u00eb vog\u00ebl t\u00eb leht\u00ebsis\u00eb q\u00eb ofron zhvillimi krahasuar me realizimin e gjith\u00eb logjik\u00ebs s\u00eb biznesit n\u00eb kodin kryesor t\u00eb aplikacionit. P\u00ebr m\u00eb tep\u00ebr, p\u00ebrpunimi i t\u00eb dh\u00ebnave n\u00eb <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/current\/plpgsql.html\">PL\/pgSQL<\/a><\/noindex> shpesh duket m\u00eb transparent dhe k\u00ebrkon m\u00eb pak kod sesa funksionaliteti i nj\u00ebjt\u00eb i shkruar n\u00eb PHP.<\/p>\n<p>Burimi: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/447746\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0426\u0435\u043b\u044c \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438 \u2014 \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 schema-keeper \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043e\u0431\u043b\u0435\u0433\u0447\u0438\u0442\u044c \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0431\u0430\u0437 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 PHP-\u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0449\u0438\u0445 \u0421\u0423\u0411\u0414 PostgreSQL. \u0418\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u0438\u0437 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438, \u0432 \u043f\u0435\u0440\u0432\u0443\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c, \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043b\u0435\u0437\u043d\u0430 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e \u043c\u0430\u043a\u0441\u0438\u043c\u0443\u043c\u0443 \u0445\u043e\u0442\u044f\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 PostgreSQL, \u043d\u043e \u0441\u0442\u0430\u043b\u043a\u0438\u0432\u0430\u044e\u0442\u0441\u044f \u0441 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430\u043c\u0438 \u0441\u043e\u043f\u0440\u043e\u0432\u043e\u0436\u0434\u0435\u043d\u0438\u044f \u0431\u0438\u0437\u043d\u0435\u0441-\u043b\u043e\u0433\u0438\u043a\u0438, \u0432\u044b\u043d\u0435\u0441\u0435\u043d\u043d\u043e\u0439 \u0432 \u0411\u0414. \u0421\u0442\u0430\u0442\u044c\u044f \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u0430 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-31385","post","type-post","status-publish","format-standard","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.2 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u0426\u0435\u043b\u044c \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438 \u2014 \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 schema-keeper \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/sq\/blog\/administrirovanie\/biznes-logika-v-baze-dannyh-pri-pomoshhi-schemakeeper\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.2\" \/>\n\t\t<meta property=\"og:locale\" content=\"sq_AL\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u0411\u0438\u0437\u043d\u0435\u0441-\u043b\u043e\u0433\u0438\u043a\u0430 \u0432 \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 SchemaKeeper | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u0426\u0435\u043b\u044c \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438 \u2014 \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 schema-keeper \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/sq\/blog\/administrirovanie\/biznes-logika-v-baze-dannyh-pri-pomoshhi-schemakeeper\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-10-31T18:40:58+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-10-31T18:40:58+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Logjika e biznesit n\u00eb baz\u00ebn e t\u00eb dh\u00ebnave me ndihm\u00ebn e SchemaKeeper | ProHoster","description":"Q\u00ebllimi i k\u00ebtij artikulli \u00ebsht\u00eb t\u00eb tregoj\u00eb mjetet q\u00eb mund t\u00eb ndihmojn\u00eb n\u00eb m\u00ebnyr\u00eb t\u00eb konsiderueshme p\u00ebrmes bibliotek\u00ebs schema-keeper.","canonical_url":"https:\/\/prohoster.info\/sq\/blog\/administrirovanie\/biznes-logika-v-baze-dannyh-pri-pomoshhi-schemakeeper","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"sq_AL","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u0411\u0438\u0437\u043d\u0435\u0441-\u043b\u043e\u0433\u0438\u043a\u0430 \u0432 \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 SchemaKeeper | ProHoster","og:description":"\u0426\u0435\u043b\u044c \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438 \u2014 \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 schema-keeper \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e.","og:url":"https:\/\/prohoster.info\/sq\/blog\/administrirovanie\/biznes-logika-v-baze-dannyh-pri-pomoshhi-schemakeeper","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-10-31T18:40:58+00:00","article:modified_time":"2019-10-31T18:40:58+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"31385","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-01-21 05:54:24","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-03-01 03:17:26","updated":"2026-01-21 05:54:24","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/posts\/31385","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/comments?post=31385"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/posts\/31385\/revisions"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/media?parent=31385"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/categories?post=31385"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/tags?post=31385"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}