{"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\/fr\/blog\/administrirovanie\/biznes-logika-v-baze-dannyh-pri-pomoshhi-schemakeeper","title":{"rendered":"Logique m\u00e9tier dans la base de donn\u00e9es \u00e0 l'aide de SchemaKeeper","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>L'objectif de cet article est de montrer, \u00e0 l'aide de la biblioth\u00e8que <noindex><a rel=\"nofollow\" href=\"https:\/\/packagist.org\/packages\/schema-keeper\/schema-keeper\">schema-keeper<\/a><\/noindex> , les outils qui permettent d'all\u00e9ger consid\u00e9rablement le processus de d\u00e9veloppement de bases de donn\u00e9es dans le cadre de projets PHP utilisant la base de donn\u00e9es PostgreSQL.<\/p>\n<p><\/p>\n<p>Les informations dans cet article seront particuli\u00e8rement utiles aux d\u00e9veloppeurs qui souhaitent tirer pleinement parti des fonctionnalit\u00e9s de PostgreSQL, mais qui rencontrent des probl\u00e8mes de maintenance de la logique m\u00e9tier int\u00e9gr\u00e9e dans la base de donn\u00e9es. <\/p>\n<p><\/p>\n<p>Cet article ne d\u00e9crira pas les avantages ou les inconv\u00e9nients de stocker la logique m\u00e9tier dans la base de donn\u00e9es. Il est suppos\u00e9 que le choix a d\u00e9j\u00e0 \u00e9t\u00e9 fait par le lecteur.<\/p>\n<p><\/p>\n<p>Les questions suivantes seront abord\u00e9es :<\/p>\n<p><\/p>\n<ol>\n<li>Comment stocker le dump de la structure de la base de donn\u00e9es dans le syst\u00e8me de contr\u00f4le de version (ci-apr\u00e8s VCS)<\/li>\n<li>Comment suivre les modifications de la structure de la base de donn\u00e9es apr\u00e8s avoir enregistr\u00e9 le dump<\/li>\n<li>Comment transf\u00e9rer les modifications de la structure de la base de donn\u00e9es vers d'autres environnements sans conflits et avec des fichiers de migration g\u00e9rables<\/li>\n<li>Comment \u00e9tablir un processus de travail parall\u00e8le sur le projet pour plusieurs d\u00e9veloppeurs<\/li>\n<li>Comment d\u00e9ployer en toute s\u00e9curit\u00e9 un plus grand nombre de modifications de la structure de la base de donn\u00e9es dans l'environnement de production<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><br \/>\n<blockquote><p><strong>SchemaKeeper<\/strong> est con\u00e7u pour travailler avec des proc\u00e9dures stock\u00e9es, \u00e9crites en <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/current\/plpgsql.html\">PL\/pgSQL<\/a><\/noindex>. Les tests avec d'autres langages n'ont pas \u00e9t\u00e9 effectu\u00e9s, donc l'utilisation peut ne pas \u00eatre aussi efficace ou possible.\n<\/p><\/blockquote>\n<\/li>\n<\/ol>\n<p><\/p>\n<h2 id=\"v-kakom-vide-hranit-damp-struktury-bd-v-vcs\">\u00c0 quel format stocker le dump de la structure de la base de donn\u00e9es dans le VCS<\/h2>\n<p><\/p>\n<p>Biblioth\u00e8que <noindex><a rel=\"nofollow\" href=\"https:\/\/packagist.org\/packages\/schema-keeper\/schema-keeper\">schema-keeper<\/a><\/noindex> fournit la fonction <code>saveDump<\/code>, qui sauvegarde la structure de tous les objets de la base de donn\u00e9es sous forme de fichiers texte s\u00e9par\u00e9s. Cela cr\u00e9e un r\u00e9pertoire contenant la structure de la base de donn\u00e9es, divis\u00e9e en fichiers group\u00e9s, faciles \u00e0 ajouter au VCS.<\/p>\n<p><\/p>\n<p>Consid\u00e9rons la conversion d'objets de la base de donn\u00e9es en fichiers \u00e0 travers plusieurs exemples :<\/p>\n<p><\/p>\n<p>Type d'objet<br \/>\nConfiguration<br \/>\nNom<br \/>\nChemin relatif vers le fichier<\/p>\n<p>Table<br \/>\npublic<br \/>\naccounts<br \/>\n<code>.\/public\/tables\/accounts.txt<\/code><\/p>\n<p>Proc\u00e9dure stock\u00e9e<br \/>\npublic<br \/>\nauth(hash bigint)<br \/>\n<code>.\/public\/functions\/auth(int8).sql<\/code><\/p>\n<p>Repr\u00e9sentation<br \/>\nbooking<br \/>\ntariffs<br \/>\n<code>.\/booking\/views\/tariffs.txt<\/code><\/p>\n<p><\/p>\n<p>Le contenu des fichiers est une repr\u00e9sentation textuelle de la structure d'un objet sp\u00e9cifique de la base de donn\u00e9es. Par exemple, pour les proc\u00e9dures stock\u00e9es, le contenu du fichier contiendra la d\u00e9finition compl\u00e8te de la proc\u00e9dure stock\u00e9e, commen\u00e7ant par le bloc <code>CREATE OR REPLACE FUNCTION<\/code>.<\/p>\n<p><\/p>\n<p>Comme on peut le voir dans le tableau ci-dessus, le chemin vers le fichier contient des informations sur le type, le sch\u00e9ma et le nom de l'objet. Cette approche facilite la navigation dans le dump et la r\u00e9vision du code des modifications dans la base de donn\u00e9es.<\/p>\n<p><\/p>\n<blockquote><p>Extension <code>.sql<\/code> Pour les fichiers de code source des proc\u00e9dures stock\u00e9es, il est choisi de sorte que l'IDE fournisse automatiquement des outils d'interaction avec la base de donn\u00e9es lors de l'ouverture du fichier.<\/p><\/blockquote>\n<p><\/p>\n<h2 id=\"kak-otslezhivat-izmeneniya-v-strukture-bd-posle-sohraneniya-dampa\">Comment suivre les modifications de la structure de la base de donn\u00e9es apr\u00e8s avoir enregistr\u00e9 le dump<\/h2>\n<p><\/p>\n<p>En sauvegardant le dump de la structure actuelle de la base de donn\u00e9es dans le VCS, nous avons la possibilit\u00e9 de v\u00e9rifier si des modifications ont \u00e9t\u00e9 apport\u00e9es \u00e0 la structure de la base de donn\u00e9es apr\u00e8s la cr\u00e9ation du dump. Dans la biblioth\u00e8que <noindex><a rel=\"nofollow\" href=\"https:\/\/packagist.org\/packages\/schema-keeper\/schema-keeper\">schema-keeper<\/a><\/noindex> une fonction est pr\u00e9vue pour d\u00e9tecter les changements dans la structure de la base de donn\u00e9es <code>verifyDump<\/code>, qui retourne, sans effets secondaires, des informations sur les diff\u00e9rences. <\/p>\n<p><\/p>\n<p>Une autre m\u00e9thode de v\u00e9rification consiste \u00e0 rappeler la fonction <code>saveDump<\/code>, en indiquant le m\u00eame r\u00e9pertoire, et \u00e0 v\u00e9rifier dans le VCS la pr\u00e9sence de changements. Comme tous les objets de la base de donn\u00e9es sont sauvegard\u00e9s dans des fichiers s\u00e9par\u00e9s, le VCS affichera uniquement les objets modifi\u00e9s.<br \/>\nLe principal inconv\u00e9nient de cette m\u00e9thode est la n\u00e9cessit\u00e9 de r\u00e9\u00e9crire les fichiers pour voir les changements.<\/p>\n<p><\/p>\n<h2 id=\"kak-perenosit-izmeneniya-v-strukture-bd-na-drugie-okruzheniya-bez-konfliktov-i-gigantskih-faylov-migraciy\">Comment transf\u00e9rer les modifications de la structure de la base de donn\u00e9es vers d'autres environnements sans conflits et avec des fichiers de migration g\u00e9rables<\/h2>\n<p><\/p>\n<p>Gr\u00e2ce \u00e0 la fonction <code>deployDump<\/code> , le code source des proc\u00e9dures stock\u00e9es peut \u00eatre modifi\u00e9 exactement comme du code source d'application ordinaire. On peut ajouter\/supprimer des lignes dans le code des proc\u00e9dures stock\u00e9es et imm\u00e9diatement envoyer les modifications dans le syst\u00e8me de contr\u00f4le de version, ou cr\u00e9er\/supprimer des proc\u00e9dures stock\u00e9es en cr\u00e9ant\/supprimant les fichiers correspondants dans le r\u00e9pertoire du dump. <\/p>\n<p><\/p>\n<p>Par exemple, pour cr\u00e9er une nouvelle proc\u00e9dure stock\u00e9e dans le sch\u00e9ma <code>public<\/code> , il suffit de cr\u00e9er un nouveau fichier avec l'extension <code>.sql<\/code> dans le r\u00e9pertoire <code>public\/functions<\/code>, d'y placer le code source de la proc\u00e9dure stock\u00e9e, y compris le bloc <code>CREATE OR REPLACE FUNCTION<\/code>, puis d'appeler la fonction <code>deployDump<\/code>. De la m\u00eame mani\u00e8re, la modification et la suppression de la proc\u00e9dure stock\u00e9e se produisent. Ainsi, le code est simultan\u00e9ment envoy\u00e9 \u00e0 la fois dans le VCS et dans la base de donn\u00e9es. <\/p>\n<p><\/p>\n<p>Si une erreur appara\u00eet dans le code source d'une proc\u00e9dure stock\u00e9e, ou s'il y a une incoh\u00e9rence entre le nom du fichier et celui de la proc\u00e9dure stock\u00e9e, alors <code>deployDump<\/code> ne s'ex\u00e9cutera pas, affichant le texte de l'erreur. L'incoh\u00e9rence entre les proc\u00e9dures stock\u00e9es du dump et de la base de donn\u00e9es actuelle est impossible lorsqu'on utilise <code>deployDump<\/code>.<\/p>\n<p><\/p>\n<blockquote><p>Lors de la cr\u00e9ation d'une nouvelle proc\u00e9dure stock\u00e9e, il n'est pas n\u00e9cessaire de saisir manuellement le bon nom de fichier. Il suffit que le fichier ait l'extension <code>.sql<\/code>. Apr\u00e8s avoir appel\u00e9 <code>deployDump<\/code> , le texte de l'erreur contiendra le bon nom qui pourra \u00eatre utilis\u00e9 pour renommer le fichier.<\/p><\/blockquote>\n<p><code>deployDump<\/code> permet de modifier les param\u00e8tres de la fonction ou le type de retour sans actions suppl\u00e9mentaires, tandis qu'avec l'approche classique, il aurait fallu<br \/>\nd'abord ex\u00e9cuter <code>DROP FUNCTION<\/code>, puis seulement <code>CREATE OR REPLACE FUNCTION<\/code>.<\/p>\n<p><\/p>\n<p>Malheureusement, il existe certaines situations o\u00f9 <code>deployDump<\/code> nous ne pouvons pas appliquer automatiquement les modifications. Par exemple, si une fonction d\u00e9clench\u00e9e est supprim\u00e9e et qu'elle est utilis\u00e9e par au moins un d\u00e9clencheur. Ces situations doivent \u00eatre r\u00e9solues manuellement \u00e0 l'aide de fichiers de migration.<\/p>\n<p><\/p>\n<p>Si le transfert des modifications dans les proc\u00e9dures stock\u00e9es est pris en charge par <noindex><a rel=\"nofollow\" href=\"https:\/\/packagist.org\/packages\/schema-keeper\/schema-keeper\">schema-keeper<\/a><\/noindex>, il est alors n\u00e9cessaire d'utiliser des fichiers de migration pour transf\u00e9rer les autres modifications dans la structure. Par exemple, une bonne biblioth\u00e8que pour travailler avec les migrations est <noindex><a rel=\"nofollow\" href=\"https:\/\/packagist.org\/packages\/doctrine\/migrations\">doctrine\/migrations<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p>Les migrations doivent \u00eatre appliqu\u00e9es avant le lancement <code>deployDump<\/code>. Cela permet d'apporter toutes les modifications \u00e0 la structure et de r\u00e9soudre les probl\u00e8mes afin que les modifications dans les proc\u00e9dures stock\u00e9es soient ensuite transf\u00e9r\u00e9es sans probl\u00e8mes.<\/p>\n<p><\/p>\n<p>Nous d\u00e9crirons plus en d\u00e9tail le travail avec les migrations dans les sections suivantes.<\/p>\n<p><\/p>\n<h2 id=\"kak-naladit-process-parallelnoy-raboty-nad-proektom-neskolkih-razrabotchikov\">Comment \u00e9tablir un processus de travail parall\u00e8le sur le projet pour plusieurs d\u00e9veloppeurs<\/h2>\n<p><\/p>\n<p>Il est n\u00e9cessaire de cr\u00e9er un script d'initialisation compl\u00e8te de la BDD, qui sera ex\u00e9cut\u00e9 par le d\u00e9veloppeur sur sa machine de travail, amenant la structure de la BDD locale en conformit\u00e9 avec le dump sauvegard\u00e9 dans le VCS. Il est plus simple de diviser l'initialisation de la BDD locale en 3 \u00e9tapes :<\/p>\n<p><\/p>\n<ol>\n<li>Importer le fichier avec la structure de base, qui s'appellera par exemple <code>base.sql<\/code> <\/li>\n<li>Application des migrations<\/li>\n<li>de system-nspawn <code>deployDump<\/code><\/li>\n<\/ol>\n<p><\/p>\n<blockquote><p><code>base.sql<\/code> \u2014 c'est le point de d\u00e9part \u00e0 partir duquel les migrations sont appliqu\u00e9es et ex\u00e9cutent <code>deployDump<\/code>, c'est-\u00e0-dire <code>base.sql + migrations + deployDump = structure actuelle de la BDD<\/code>. On peut former ce fichier \u00e0 l'aide de l'utilitaire <code>pg_dump<\/code>. Il est utilis\u00e9 <code>base.sql<\/code> uniquement lors de l'initialisation de la base de donn\u00e9es \u00e0 partir de z\u00e9ro.<\/p><\/blockquote>\n<p>Nommons le script d'initialisation compl\u00e8te de la BDD <code>refresh.sh<\/code>. Le flux de travail peut ressembler \u00e0 ceci :<\/p>\n<p><\/p>\n<ol>\n<li>Le d\u00e9veloppeur ex\u00e9cute dans son environnement <code>refresh.sh<\/code> et obtient la structure actuelle de la BDD<\/li>\n<li>Le d\u00e9veloppeur commence \u00e0 travailler sur la t\u00e2che assign\u00e9e, en modifiant la BDD locale pour les besoins de la nouvelle fonctionnalit\u00e9 (<code>ALTER TABLE ... ADD COLUMN<\/code> etc.)<\/li>\n<li>Apr\u00e8s avoir termin\u00e9 la t\u00e2che, le d\u00e9veloppeur appelle la fonction <code>saveDump<\/code>, pour enregistrer les modifications apport\u00e9es \u00e0 la BDD dans le VCS.<\/li>\n<li>Le d\u00e9veloppeur relance <code>refresh.sh<\/code>, puis <code>verifyDump<\/code>, qui affiche d\u00e9sormais la liste des changements \u00e0 inclure dans la migration.<\/li>\n<li>Le d\u00e9veloppeur transf\u00e8re toutes les modifications de structure dans le fichier de migration, relance \u00e0 nouveau <code>refresh.sh<\/code> et <code>verifyDump<\/code>, et si la migration est correctement r\u00e9dig\u00e9e, <code>verifyDump<\/code> il montrera qu'il n'y a pas de diff\u00e9rences entre la BDD locale et le dump sauvegard\u00e9.<\/li>\n<\/ol>\n<p><\/p>\n<p>Le processus d\u00e9crit ci-dessus est compatible avec les principes de gitflow. Chaque branche dans le VCS contiendra sa propre version du dump, et lors de la fusion des branches, les dumps seront \u00e9galement fusionn\u00e9s. Dans la plupart des cas, aucune action suppl\u00e9mentaire n'est n\u00e9cessaire apr\u00e8s la fusion, mais si des modifications ont \u00e9t\u00e9 apport\u00e9es dans diff\u00e9rentes branches, par exemple dans la m\u00eame table, un conflit peut survenir.<\/p>\n<p><\/p>\n<p>Consid\u00e9rons une situation conflictuelle \u00e0 titre d'exemple : il y a une branche <em>develop<\/em>, \u00e0 partir de laquelle deux branches ont \u00e9t\u00e9 cr\u00e9\u00e9es : <em>feature1<\/em> et <em>feature2<\/em>, qui n'ont pas de conflits avec <em>develop<\/em>, mais ont des conflits entre elles. L'objectif est de fusionner les deux branches dans <em>develop<\/em>. Dans ce cas, il est recommand\u00e9 de d'abord fusionner l'une des branches dans <em>develop<\/em>, puis de fusionner <em>develop<\/em> dans la branche restante, en r\u00e9solvant ainsi les conflits dans la branche restante, puis de r\u00e9aliser la fusion de la derni\u00e8re branche dans <em>develop<\/em>. Lors de la r\u00e9solution des conflits, il peut \u00eatre n\u00e9cessaire de corriger le fichier de migration dans la derni\u00e8re branche pour qu'il corresponde au dump final, qui inclut les r\u00e9sultats des fusions.<\/p>\n<p><\/p>\n<h2 id=\"kak-bezopasno-deploit-bolshee-kolichestvo-izmeneniy-v-strukture-bd-na-production-okruzhenie\">Comment d\u00e9ployer en toute s\u00e9curit\u00e9 un plus grand nombre de modifications de la structure de la base de donn\u00e9es dans l'environnement de production<\/h2>\n<p><\/p>\n<p>Gr\u00e2ce \u00e0 la pr\u00e9sence d'un dump de la structure actuelle de la base de donn\u00e9es dans le VCS, il est possible de v\u00e9rifier si la base de production correspond exactement \u00e0 la structure requise. Cela garantit que toutes les modifications con\u00e7ues par les d\u00e9veloppeurs ont \u00e9t\u00e9 correctement transf\u00e9r\u00e9es \u00e0 la base de production.<\/p>\n<p><\/p>\n<p>Puisque <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/current\/ddl.html\">DDL<\/a><\/noindex> dans PostgreSQL est <noindex><a rel=\"nofollow\" href=\"https:\/\/wiki.postgresql.org\/wiki\/Transactional_DDL_in_PostgreSQL:_A_Competitive_Analysis\">transactionnelle<\/a><\/noindex>, il est recommand\u00e9 de suivre l'ordre de d\u00e9ploiement suivant, afin qu'en cas d'erreur impr\u00e9vue, la restauration soit \u00ab indolore \u00bb : <code>ROLLBACK<\/code>:<\/p>\n<p><\/p>\n<ol>\n<li>Commencer la transaction<\/li>\n<li>Dans la transaction, ex\u00e9cuter toutes les migrations<\/li>\n<li>Dans cette m\u00eame transaction, effectuer <code>deployDump<\/code><\/li>\n<li>Sans terminer la transaction, ex\u00e9cuter <code>verifyDump<\/code>. S'il n'y a pas d'erreurs, ex\u00e9cuter <code>COMMIT<\/code>. S'il y a des erreurs, ex\u00e9cuter <code>ROLLBACK<\/code><\/li>\n<\/ol>\n<p><\/p>\n<p>Ces \u00e9tapes s'int\u00e8grent assez facilement dans les approches existantes de d\u00e9ploiement d'applications, y compris les d\u00e9ploiements sans temps d'arr\u00eat.<\/p>\n<p><\/p>\n<h1 id=\"zaklyuchenie\">Conclusion<\/h1>\n<p><\/p>\n<p>Gr\u00e2ce aux m\u00e9thodes d\u00e9crites ci-dessus, il est possible d'extraire un maximum de performance des projets \u00ab PHP + PostgreSQL \u00bb, au d\u00e9triment d'un confort de d\u00e9veloppement relativement faible compar\u00e9 \u00e0 la mise en \u0153uvre de toute la logique m\u00e9tier dans le code principal de l'application. De plus, le traitement des donn\u00e9es dans <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/current\/plpgsql.html\">PL\/pgSQL<\/a><\/noindex> semble souvent plus transparent et n\u00e9cessite moins de code que la m\u00eame fonctionnalit\u00e9 \u00e9crite en PHP.<\/p>\n<p>Source : <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\/fr\/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=\"fr_FR\" \/>\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\/fr\/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\udd47La logique m\u00e9tier dans la base de donn\u00e9es gr\u00e2ce \u00e0 SchemaKeeper | ProHoster","description":"L'objectif de cet article est de d\u00e9montrer, \u00e0 travers la biblioth\u00e8que schema-keeper, des outils qui permettent d'am\u00e9liorer consid\u00e9rablement.","canonical_url":"https:\/\/prohoster.info\/fr\/blog\/administrirovanie\/biznes-logika-v-baze-dannyh-pri-pomoshhi-schemakeeper","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"fr_FR","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\/fr\/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\/fr\/wp-json\/wp\/v2\/posts\/31385","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/comments?post=31385"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/posts\/31385\/revisions"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/media?parent=31385"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/categories?post=31385"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/tags?post=31385"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}