{"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\/it\/blog\/administrirovanie\/biznes-logika-v-baze-dannyh-pri-pomoshhi-schemakeeper","title":{"rendered":"Logica di business nel database tramite SchemaKeeper","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Lo scopo di questo articolo \u00e8, attraverso la libreria <noindex><a rel=\"nofollow\" href=\"https:\/\/packagist.org\/packages\/schema-keeper\/schema-keeper\">schema-keeper<\/a><\/noindex> mostrare gli strumenti che possono semplificare notevolmente il processo di sviluppo di database all'interno di progetti PHP che utilizzano il DBMS PostgreSQL.<\/p>\n<p><\/p>\n<p>Le informazioni contenute in questo articolo saranno particolarmente utili ai programmatori che desiderano sfruttare al meglio le potenzialit\u00e0 di PostgreSQL, ma si trovano di fronte a problemi di manutenzione della logica di business trasferita nel database. <\/p>\n<p><\/p>\n<p>L'articolo non tratter\u00e0 i vantaggi o gli svantaggi di memorizzare la logica di business nel database. Si presuppone che la scelta sia gi\u00e0 stata effettuata dal lettore.<\/p>\n<p><\/p>\n<p>Saranno affrontate le seguenti questioni:<\/p>\n<p><\/p>\n<ol>\n<li>In quale formato memorizzare il dump della struttura del database nel sistema di controllo versione (d'ora in poi - VCS)<\/li>\n<li>Come monitorare le modifiche alla struttura del database dopo aver salvato il dump<\/li>\n<li>Come trasferire le modifiche alla struttura del database su altri ambienti senza conflitti e migrazioni di grandi dimensioni<\/li>\n<li>Come organizzare il lavoro parallelo di pi\u00f9 sviluppatori su un progetto<\/li>\n<li>Come implementare in sicurezza un numero maggiore di modifiche alla struttura del database nell'ambiente di produzione<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><br \/>\n<blockquote><p><strong>SchemaKeeper<\/strong> \u00e8 progettato per lavorare con procedure memorizzate scritte nel linguaggio <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/current\/plpgsql.html\">PL\/pgSQL<\/a><\/noindex>. Non sono stati condotti test con altre lingue, quindi l'uso potrebbe non essere altrettanto efficace o addirittura impossibile.\n<\/p><\/blockquote>\n<\/li>\n<\/ol>\n<p><\/p>\n<h2 id=\"v-kakom-vide-hranit-damp-struktury-bd-v-vcs\">In quale forma conservare il dump della struttura del DB in VCS<\/h2>\n<p><\/p>\n<p>Libreria <noindex><a rel=\"nofollow\" href=\"https:\/\/packagist.org\/packages\/schema-keeper\/schema-keeper\">schema-keeper<\/a><\/noindex> fornisce la funzione <code>saveDump<\/code>, che salva la struttura di tutti gli oggetti del DB come singoli file di testo. In uscita viene creata una directory contenente la struttura del DB suddivisa in file raggruppati, facilmente aggiungibili al VCS.<\/p>\n<p><\/p>\n<p>Consideriamo la trasformazione degli oggetti del DB in file in diversi esempi:<\/p>\n<p><\/p>\n<p>Tipo di oggetto<br \/>\nSchema<br \/>\nNome<br \/>\nPercorso relativo al file<\/p>\n<p>Tabella<br \/>\npubblico<br \/>\naccounts<br \/>\n<code>.\/public\/tables\/accounts.txt<\/code><\/p>\n<p>Procedura memorizzata<br \/>\npubblico<br \/>\nauth(hash bigint)<br \/>\n<code>.\/public\/functions\/auth(int8).sql<\/code><\/p>\n<p>Vista<br \/>\nbooking<br \/>\ntariffs<br \/>\n<code>.\/booking\/views\/tariffs.txt<\/code><\/p>\n<p><\/p>\n<p>Il contenuto dei file \u00e8 una rappresentazione testuale della struttura di un oggetto specifico del DB. Ad esempio, per le procedure memorizzate, il contenuto del file sar\u00e0 la definizione completa della procedura memorizzata, che inizia con il blocco <code>CREATE OR REPLACE FUNCTION<\/code>.<\/p>\n<p><\/p>\n<p>Come si pu\u00f2 vedere dalla tabella sopra, il percorso del file contiene informazioni sul tipo, schema e nome dell'oggetto. Questo approccio facilita la navigazione nel dump e la revisione del codice delle modifiche nel DB.<\/p>\n<p><\/p>\n<blockquote><p>Espansione <code>.sql<\/code> per i file con il codice sorgente delle procedure archiviate, \u00e8 stato scelto affinch\u00e9 l'IDE fornisca automaticamente gli strumenti per interagire con il database all'apertura del file.<\/p><\/blockquote>\n<p><\/p>\n<h2 id=\"kak-otslezhivat-izmeneniya-v-strukture-bd-posle-sohraneniya-dampa\">Come monitorare le modifiche alla struttura del database dopo aver salvato il dump<\/h2>\n<p><\/p>\n<p>Salvando il dump della struttura attuale del database nel VCS, otteniamo la possibilit\u00e0 di verificare se sono state apportate modifiche alla struttura del database dopo la creazione del dump. Nella libreria <noindex><a rel=\"nofollow\" href=\"https:\/\/packagist.org\/packages\/schema-keeper\/schema-keeper\">schema-keeper<\/a><\/noindex> per identificare le modifiche nella struttura del database \u00e8 prevista la funzione <code>verifyDump<\/code>, che restituisce informazioni sulle differenze senza effetti collaterali. <\/p>\n<p><\/p>\n<p>Un metodo alternativo di controllo consiste nel richiamare nuovamente la funzione <code>saveDump<\/code>, specificando la stessa directory e verificando nel VCS la presenza di modifiche. Poich\u00e9 tutti gli oggetti del database sono salvati in file separati, il VCS mostrer\u00e0 solo gli oggetti modificati.<br \/>\nIl principale svantaggio di questo metodo \u00e8 la necessit\u00e0 di riscrivere i file per vedere le modifiche.<\/p>\n<p><\/p>\n<h2 id=\"kak-perenosit-izmeneniya-v-strukture-bd-na-drugie-okruzheniya-bez-konfliktov-i-gigantskih-faylov-migraciy\">Come trasferire le modifiche alla struttura del database su altri ambienti senza conflitti e migrazioni di grandi dimensioni<\/h2>\n<p><\/p>\n<p>Grazie alla funzione <code>deployDump<\/code> Il codice sorgente delle stored procedure pu\u00f2 essere modificato esattamente come il codice sorgente di un'applicazione normale. \u00c8 possibile aggiungere o rimuovere nuove righe nel codice delle stored procedure e inviare immediatamente le modifiche nel sistema di controllo versione, oppure creare o eliminare stored procedure creando o eliminando i relativi file nella directory di backup. <\/p>\n<p><\/p>\n<p>Ad esempio, per creare una nuova stored procedure nello schema <code>pubblico<\/code> \u00e8 sufficiente creare un nuovo file con estensione <code>.sql<\/code> nella directory <code>public\/functions<\/code>, inserire il codice sorgente della stored procedure, incluso il blocco <code>CREATE OR REPLACE FUNCTION<\/code>, e poi chiamare la funzione <code>deployDump<\/code>. Lo stesso vale per la modifica e la rimozione di una stored procedure. In questo modo, il codice finisce sia nel VCS che nel database. <\/p>\n<p><\/p>\n<p>Se nel codice sorgente di una qualsiasi stored procedure si verifica un errore, o c'\u00e8 una discrepanza tra il nome del file e la stored procedure, allora <code>deployDump<\/code> non verr\u00e0 eseguita, mostrando il messaggio di errore. La discrepanza tra le stored procedure nel dump e l'attuale DB non \u00e8 possibile utilizzando <code>deployDump<\/code>.<\/p>\n<p><\/p>\n<blockquote><p>Quando si crea una nuova stored procedure, non \u00e8 necessario immettere manualmente il nome corretto del file. \u00c8 sufficiente che il file abbia l'estensione <code>.sql<\/code>. Dopo la chiamata <code>deployDump<\/code> il messaggio di errore conterr\u00e0 il nome corretto che pu\u00f2 essere utilizzato per rinominare il file.<\/p><\/blockquote>\n<p><code>deployDump<\/code> permette di modificare i parametri di funzione o il tipo di ritorno senza ulteriori azioni, mentre con l'approccio classico sarebbe stato necessario<br \/>\neseguire prima <code>DROP FUNCTION<\/code>, e solo dopo <code>CREATE OR REPLACE FUNCTION<\/code>.<\/p>\n<p><\/p>\n<p>Sfortunatamente, ci sono alcune situazioni in cui <code>deployDump<\/code> non \u00e8 possibile applicare automaticamente le modifiche. Ad esempio, se si elimina una funzione di trigger utilizzata da almeno un trigger. Tali situazioni devono essere risolte manualmente utilizzando file di migrazione.<\/p>\n<p><\/p>\n<p>Se il trasferimento delle modifiche nelle procedure memorizzate \u00e8 gestito dallo stesso <noindex><a rel=\"nofollow\" href=\"https:\/\/packagist.org\/packages\/schema-keeper\/schema-keeper\">schema-keeper<\/a><\/noindex>, per trasferire le altre modifiche nella struttura \u00e8 necessario utilizzare file di migrazione. Ad esempio, una buona libreria per la gestione delle migrazioni \u00e8 <noindex><a rel=\"nofollow\" href=\"https:\/\/packagist.org\/packages\/doctrine\/migrations\">doctrine\/migrations<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p>Le migrazioni devono essere applicate prima di avviare <code>deployDump<\/code>. Questo consente di apportare tutte le modifiche alla struttura e risolvere situazioni problematiche affinch\u00e9 le modifiche nelle procedure memorizzate siano trasferite senza problemi in seguito.<\/p>\n<p><\/p>\n<p>Lavorare con le migrazioni sar\u00e0 descritto pi\u00f9 dettagliatamente nei capitoli successivi.<\/p>\n<p><\/p>\n<h2 id=\"kak-naladit-process-parallelnoy-raboty-nad-proektom-neskolkih-razrabotchikov\">Come organizzare il lavoro parallelo di pi\u00f9 sviluppatori su un progetto<\/h2>\n<p><\/p>\n<p>\u00c8 necessario creare uno script per l'inizializzazione completa del database che verr\u00e0 eseguito dallo sviluppatore sulla propria macchina, allineando la struttura del database locale a quella del dump salvato nel VCS. \u00c8 pi\u00f9 semplice dividere l'inizializzazione del database locale in 3 fasi:<\/p>\n<p><\/p>\n<ol>\n<li>Importazione di un file con la struttura di base, che si chiamer\u00e0, ad esempio, <code>base.sql<\/code> <\/li>\n<li>Applicazione delle migrazioni<\/li>\n<li>La chiamata <code>deployDump<\/code><\/li>\n<\/ol>\n<p><\/p>\n<blockquote><p><code>base.sql<\/code> \u00e8 il punto di partenza, sopra il quale vengono applicate le migrazioni e viene eseguito <code>deployDump<\/code>, vale a dire <code>base.sql + migrazioni + deployDump = struttura attuale del database<\/code>. \u00c8 possibile generare un tale file utilizzando l'utility <code>pg_dump<\/code>. Viene utilizzato <code>base.sql<\/code> esclusivamente per l'inizializzazione del database da zero.<\/p><\/blockquote>\n<p>Chiamiamo lo script per l'inizializzazione completa del database <code>refresh.sh<\/code>. Il flusso di lavoro potrebbe apparire come segue:<\/p>\n<p><\/p>\n<ol>\n<li>Lo sviluppatore esegue nel proprio ambiente <code>refresh.sh<\/code> e ottiene la struttura attuale del database<\/li>\n<li>Lo sviluppatore inizia a lavorare sul compito assegnato, modificando il database locale in base alle esigenze della nuova funzionalit\u00e0 (<code>ALTER TABLE ... ADD COLUMN<\/code> ecc.)<\/li>\n<li>Dopo aver completato il compito, lo sviluppatore chiama la funzione <code>saveDump<\/code>, per registrare nel VCS le modifiche apportate al database<\/li>\n<li>Lo sviluppatore esegue nuovamente <code>refresh.sh<\/code>, poi <code>verifyDump<\/code>, che ora mostra l'elenco delle modifiche da includere nella migrazione<\/li>\n<li>Lo sviluppatore trasferisce tutte le modifiche della struttura nel file di migrazione e lo esegue di nuovo <code>refresh.sh<\/code> e <code>verifyDump<\/code>, e, se la migrazione \u00e8 stata compilata correttamente, <code>verifyDump<\/code> mostrer\u00e0 l'assenza di differenze tra il database locale e il dump salvato<\/li>\n<\/ol>\n<p><\/p>\n<p>Il processo descritto sopra \u00e8 compatibile con i principi di gitflow. Ogni branch nel VCS conterr\u00e0 la propria versione del dump, e durante la fusione dei branch avverr\u00e0 la fusione dei dump. Nella maggior parte dei casi, dopo la fusione non \u00e8 necessario intraprendere ulteriori azioni, ma se in branch diversi sono state apportate modifiche, ad esempio, alla stessa tabella, potrebbe sorgere un conflitto.<\/p>\n<p><\/p>\n<p>Consideriamo una situazione di conflitto, ad esempio: c'\u00e8 un branch <em>develop<\/em>, da cui si diramano due branch: <em>feature1<\/em> e <em>feature2<\/em>, che non presentano conflitti con <em>develop<\/em>, ma hanno conflitti tra di loro. L'obiettivo \u00e8 eseguire la fusione di entrambi i branch in <em>develop<\/em>. Per questo caso, \u00e8 consigliabile prima eseguire la fusione di uno dei branch in <em>develop<\/em>, e poi la fusione di <em>develop<\/em> nell'altro branch, risolvendo i conflitti in quest'ultimo, dopodich\u00e9 eseguire la fusione dell'ultimo branch in <em>develop<\/em>. Nella fase di risoluzione dei conflitti potrebbe essere necessario modificare il file di migrazione nell'ultima branch affinch\u00e9 corrisponda al dump finale, includendo i risultati delle fusioni.<\/p>\n<p><\/p>\n<h2 id=\"kak-bezopasno-deploit-bolshee-kolichestvo-izmeneniy-v-strukture-bd-na-production-okruzhenie\">Come implementare in sicurezza un numero maggiore di modifiche alla struttura del database nell'ambiente di produzione<\/h2>\n<p><\/p>\n<p>Grazie alla presenza nel VCS di un dump della struttura attuale del database, \u00e8 possibile verificare che il database di produzione corrisponda esattamente alla struttura richiesta. Questo garantisce che tutte le modifiche pensate dagli sviluppatori siano state trasferite con successo nel database di produzione.<\/p>\n<p><\/p>\n<p>Poich\u00e9 <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/current\/ddl.html\">DDL<\/a><\/noindex> in PostgreSQL \u00e8 <noindex><a rel=\"nofollow\" href=\"https:\/\/wiki.postgresql.org\/wiki\/Transactional_DDL_in_PostgreSQL:_A_Competitive_Analysis\">transactional<\/a><\/noindex>, si raccomanda di seguire il seguente ordine di deployment, affinch\u00e9, in caso di errore imprevisto, si possa eseguire un'operazione \"indolore\". <code>ROLLBACK<\/code>:<\/p>\n<p><\/p>\n<ol>\n<li>Iniziare la transazione<\/li>\n<li>Eseguire tutte le migrazioni nella transazione<\/li>\n<li>Nella stessa transazione eseguire <code>deployDump<\/code><\/li>\n<li>Senza terminare la transazione, eseguire <code>verifyDump<\/code>. Se non ci sono errori, eseguire <code>COMMIT<\/code>. Se ci sono errori, eseguire <code>ROLLBACK<\/code><\/li>\n<\/ol>\n<p><\/p>\n<p>Questi passaggi si integrano facilmente con gli approcci esistenti per il deployment delle applicazioni, incluso il zero-downtime.<\/p>\n<p><\/p>\n<h1 id=\"zaklyuchenie\">Conclusione<\/h1>\n<p><\/p>\n<p>Grazie ai metodi sopra descritti, \u00e8 possibile massimizzare le prestazioni dei progetti \"PHP + PostgreSQL\", sacrificando una quantit\u00e0 relativamente modesta di comodit\u00e0 nello sviluppo rispetto all'implementazione dell'intera logica di business nel codice principale dell'applicazione. Inoltre, l'elaborazione dei dati in <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/current\/plpgsql.html\">PL\/pgSQL<\/a><\/noindex> spesso appare pi\u00f9 trasparente e richiede meno codice rispetto alla stessa funzionalit\u00e0 scritta in PHP.<\/p>\n<p>Fonte: <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.0.1 - 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 \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\" \/>\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\/it\/blog\/administrirovanie\/biznes-logika-v-baze-dannyh-pri-pomoshhi-schemakeeper\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.0.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"it_IT\" \/>\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 \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\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/it\/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\udd47Logica di business nel database con SchemaKeeper | ProHoster","description":"L'obiettivo di questo articolo \u00e8 dimostrare, tramite la libreria schema-keeper, gli strumenti che consentono di semplificare notevolmente il processo di sviluppo dei database nei progetti PHP che utilizzano il SGBD PostgreSQL. Le informazioni in questo articolo saranno principalmente utili agli sviluppatori che desiderano sfruttare al massimo le potenzialit\u00e0 di PostgreSQL, ma che si trovano ad affrontare problemi nella gestione della logica di business spostata nel database. L'articolo non descriver\u00e0 i vantaggi","canonical_url":"https:\/\/prohoster.info\/it\/blog\/administrirovanie\/biznes-logika-v-baze-dannyh-pri-pomoshhi-schemakeeper","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"it_IT","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 \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","og:url":"https:\/\/prohoster.info\/it\/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\/it\/wp-json\/wp\/v2\/posts\/31385","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/comments?post=31385"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/posts\/31385\/revisions"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/media?parent=31385"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/categories?post=31385"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/tags?post=31385"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}