{"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 aziendale nel database tramite SchemaKeeper","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>L'obiettivo di questo articolo \u00e8 illustrare, attraverso la libreria <noindex><a rel=\"nofollow\" href=\"https:\/\/packagist.org\/packages\/schema-keeper\/schema-keeper\">schema-keeper<\/a><\/noindex> , gli strumenti che consentono di 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 di questo articolo saranno utili in primo luogo agli sviluppatori che desiderano sfruttare al massimo le potenzialit\u00e0 di PostgreSQL, ma che si trovano ad affrontare problemi di manutenzione della logica aziendale spostata nel database. <\/p>\n<p><\/p>\n<p>L'articolo non descriver\u00e0 i vantaggi o gli svantaggi di conservare la logica aziendale nel database. Si presume che la scelta sia gi\u00e0 stata fatta dal lettore.<\/p>\n<p><\/p>\n<p>Saranno esaminati i seguenti punti:<\/p>\n<p><\/p>\n<ol>\n<li>In quale formato conservare il dump della struttura del database nel sistema di controllo versione (di seguito 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 in altri ambienti senza conflitti e senza giganteschi file di migrazione<\/li>\n<li>Come organizzare il lavoro parallelo su un progetto da parte di pi\u00f9 sviluppatori<\/li>\n<li>Come implementare in modo sicuro 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>. I test con altri linguaggi non sono stati effettuati, pertanto l'uso potrebbe non essere altrettanto efficace o potrebbe essere 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 formato conservare il dump della struttura del database nel VCS<\/h2>\n<p><\/p>\n<p>La 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 dal database come singoli file di testo. In output viene creata una directory contenente la struttura del database, suddivisa in file raggruppati, che possono essere facilmente aggiunti al VCS.<\/p>\n<p><\/p>\n<p>Esaminiamo la trasformazione degli oggetti dal database in file con alcuni 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>Rappresentazione<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 particolare oggetto del database. 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, sullo schema e sul nome dell'oggetto. Questo approccio facilita la navigazione nel dump e la revisione del codice delle modifiche nel database.<\/p>\n<p><\/p>\n<blockquote><p>Estensione <code>.sql<\/code> per i file con codice sorgente delle procedure memorizzate, \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 in 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> \u00e8 prevista una funzione per rilevare le modifiche nella struttura del database <code>verifyDump<\/code>, che restituisce informazioni sulle differenze senza effetti collaterali. <\/p>\n<p><\/p>\n<p>Un modo alternativo per controllare \u00e8 richiamare nuovamente la funzione <code>saveDump<\/code>, specificando la stessa directory, e controllare in VCS la presenza di modifiche. Poich\u00e9 tutti gli oggetti del database sono salvati in file separati, VCS mostrer\u00e0 solo gli oggetti modificati.<br \/>\nIl principale svantaggio di questo metodo \u00e8 la necessit\u00e0 di sovrascrivere i file per visualizzare 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 in altri ambienti senza conflitti e senza giganteschi file di migrazione<\/h2>\n<p><\/p>\n<p>Grazie alla funzione <code>deployDump<\/code> , il codice sorgente delle procedure memorizzate pu\u00f2 essere modificato esattamente come il codice sorgente dell'applicazione. \u00c8 possibile aggiungere\/rimuovere nuove righe nel codice delle procedure memorizzate e inviare immediatamente le modifiche nel sistema di controllo versione, oppure creare\/rimuovere procedure memorizzate creando\/rimuovendo i corrispondenti file nella directory del dump. <\/p>\n<p><\/p>\n<p>Ad esempio, per creare una nuova procedura memorizzata 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 procedura memorizzata, incluso il blocco <code>CREATE OR REPLACE FUNCTION<\/code>, e poi richiamare la funzione <code>deployDump<\/code>. Allo stesso modo avviene la modifica e la rimozione della procedura memorizzata. In questo modo, il codice entra sia in VCS che nel database. <\/p>\n<p><\/p>\n<p>Se nel codice sorgente di una qualsiasi procedura memorizzata si verifica un errore, oppure un'incongruenza tra il nome del file e la procedura memorizzata, allora <code>deployDump<\/code> non verr\u00e0 eseguita, mostrando il testo dell'errore. La discordanza delle procedure memorizzate tra il dump e il database attuale \u00e8 impossibile utilizzando <code>deployDump<\/code>.<\/p>\n<p><\/p>\n<blockquote><p>Quando si crea una nuova procedura memorizzata, 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 testo dell'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 della funzione o il tipo di ritorno senza ulteriori azioni, mentre nell'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>Purtroppo, ci sono alcune situazioni in cui <code>deployDump<\/code> non \u00e8 possibile applicare automaticamente le modifiche. Ad esempio, se viene rimossa una funzione di trigger utilizzata da almeno un trigger. Queste situazioni devono essere gestite manualmente utilizzando i file di migrazione.<\/p>\n<p><\/p>\n<p>Se il trasferimento delle modifiche nelle procedure memorizzate \u00e8 responsabilit\u00e0 dello <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 i file di migrazione. Ad esempio, una buona libreria per lavorare con le 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 dell'avvio <code>deployDump<\/code>. Questo consente di apportare tutte le modifiche alla struttura e risolvere le situazioni problematiche, affinch\u00e9 le modifiche nelle procedure memorizzate possano successivamente essere trasferite senza problemi.<\/p>\n<p><\/p>\n<p>Un'analisi pi\u00f9 dettagliata del lavoro con le migrazioni sar\u00e0 fornita nei capitoli successivi.<\/p>\n<p><\/p>\n<h2 id=\"kak-naladit-process-parallelnoy-raboty-nad-proektom-neskolkih-razrabotchikov\">Come organizzare il lavoro parallelo su un progetto da parte di pi\u00f9 sviluppatori<\/h2>\n<p><\/p>\n<p>\u00c8 necessario creare uno script per l'inizializzazione completa del database, che sar\u00e0 eseguito dallo sviluppatore sulla propria macchina di lavoro, allineando la struttura del database locale a quella salvata nel dump VCS. La cosa pi\u00f9 semplice \u00e8 suddividere l'inizializzazione del database locale in 3 passaggi:<\/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>Chiamata <code>deployDump<\/code><\/li>\n<\/ol>\n<p><\/p>\n<blockquote><p><code>base.sql<\/code> \u00e8 il punto di partenza, su cui vengono applicate le migrazioni e viene eseguito <code>deployDump<\/code>, cio\u00e8 <code>base.sql + migrazioni + deployDump = struttura attuale del database<\/code>. Un file di questo tipo pu\u00f2 essere generato con il supporto di un'utilit\u00e0. <code>pg_dump<\/code>Utilizzato <code>base.sql<\/code> esclusivamente durante l'inizializzazione del database da zero.<\/p><\/blockquote>\n<p>Chiameremo lo script per l'inizializzazione completa del database <code>refresh.sh<\/code>. Il processo di lavoro pu\u00f2 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 per soddisfare le 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 in VCS le modifiche apportate al database<\/li>\n<li>Lo sviluppatore esegue nuovamente <code>refresh.sh<\/code>, quindi <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, 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 si verificher\u00e0 una fusione dei dump. Nella maggior parte dei casi, dopo la fusione non \u00e8 necessario intraprendere ulteriori azioni, ma se sono state apportate modifiche in branch diversi, ad esempio nella 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 hanno conflitti con <em>develop.<\/em>, ma hanno conflitti tra di loro. \u00c8 necessario effettuare la fusione di entrambi i branch in <em>develop.<\/em>. In questo caso, \u00e8 consigliabile prima eseguire la fusione di uno dei branch in <em>develop.<\/em>, e poi effettuare la fusione <em>develop.<\/em> nell'altro branch, risolvendo i conflitti in quest'ultimo branch, dopodich\u00e9 eseguire la fusione dell'ultimo branch in <em>develop.<\/em>. Durante la fase di risoluzione dei conflitti, potrebbe essere necessario correggere il file di migrazione nell'ultimo branch per farlo corrispondere al dump finale, che include 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 modo sicuro un numero maggiore di modifiche alla struttura del database nell'ambiente di produzione<\/h2>\n<p><\/p>\n<p>Grazie alla disponibilit\u00e0 nel VCS di un dump della struttura attuale del database, diventa possibile verificare il database di produzione per la corrispondenza esatta con la struttura richiesta. Questo garantisce che tutte le modifiche previste 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\">transazionale<\/a><\/noindex>, si raccomanda di seguire il seguente ordine di deployment, in modo che, in caso di errore imprevisto, si possa eseguire senza problemi <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 chiudere 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 abbastanza facilmente nei metodi esistenti per il deployment delle applicazioni, inclusi quelli a zero downtime.<\/p>\n<p><\/p>\n<h1 id=\"zaklyuchenie\">Conclusione<\/h1>\n<p><\/p>\n<p>Grazie ai metodi descritti sopra, \u00e8 possibile ottenere il massimo dalle performance dei progetti \"PHP + PostgreSQL\", sacrificando per\u00f2 relativamente poca comodit\u00e0 nello sviluppo rispetto all'implementazione di tutta la 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.1.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.\" \/>\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.1.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.\" \/>\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 aziendale nel database con SchemaKeeper | ProHoster","description":"L'obiettivo di questo articolo \u00e8 mostrare, attraverso la libreria schema-keeper, gli strumenti che consentono di farlo in modo sostanziale.","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.","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}]}}