{"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\/es\/blog\/administrirovanie\/biznes-logika-v-baze-dannyh-pri-pomoshhi-schemakeeper","title":{"rendered":"L\u00f3gica empresarial en la base de datos mediante SchemaKeeper","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>El objetivo de este art\u00edculo es, a trav\u00e9s de la biblioteca <noindex><a rel=\"nofollow\" href=\"https:\/\/packagist.org\/packages\/schema-keeper\/schema-keeper\">schema-keeper<\/a><\/noindex> mostrar herramientas que permiten facilitar considerablemente el proceso de desarrollo de bases de datos en proyectos PHP que utilizan el SGBD PostgreSQL.<\/p>\n<p><\/p>\n<p>La informaci\u00f3n de este art\u00edculo ser\u00e1 especialmente \u00fatil para desarrolladores que desean aprovechar al m\u00e1ximo las capacidades de PostgreSQL, pero se enfrentan a problemas de mantenimiento de la l\u00f3gica de negocio que se ha trasladado a la base de datos. <\/p>\n<p><\/p>\n<p>Este art\u00edculo no describir\u00e1 las ventajas o desventajas de almacenar la l\u00f3gica de negocio en la base de datos. Se asume que el lector ya ha tomado esta decisi\u00f3n.<\/p>\n<p><\/p>\n<p>Se abordar\u00e1n las siguientes cuestiones:<\/p>\n<p><\/p>\n<ol>\n<li>\u00bfEn qu\u00e9 formato almacenar el volcado de la estructura de la base de datos en el sistema de control de versiones (en adelante VCS)?<\/li>\n<li>\u00bfC\u00f3mo rastrear cambios en la estructura de la base de datos despu\u00e9s de guardar el volcado?<\/li>\n<li>\u00bfC\u00f3mo trasladar los cambios en la estructura de la base de datos a otros entornos sin conflictos y con archivos de migraci\u00f3n reducidos?<\/li>\n<li>\u00bfC\u00f3mo establecer el proceso de trabajo paralelo en el proyecto entre varios desarrolladores?<\/li>\n<li>\u00bfC\u00f3mo desplegar de manera segura una mayor cantidad de cambios en la estructura de la base de datos en el entorno de producci\u00f3n?<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><br \/>\n<blockquote><p><strong>SchemaKeeper<\/strong> est\u00e1 dise\u00f1ado para trabajar con procedimientos almacenados escritos en el lenguaje <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/current\/plpgsql.html\">PL\/pgSQL<\/a><\/noindex>. No se ha probado con otros lenguajes, por lo que su uso puede no ser tan eficiente o incluso ser imposible.\n<\/p><\/blockquote>\n<\/li>\n<\/ol>\n<p><\/p>\n<h2 id=\"v-kakom-vide-hranit-damp-struktury-bd-v-vcs\">\u00bfEn qu\u00e9 formato almacenar el volcado de la estructura de la base de datos en VCS?<\/h2>\n<p><\/p>\n<p>La biblioteca <noindex><a rel=\"nofollow\" href=\"https:\/\/packagist.org\/packages\/schema-keeper\/schema-keeper\">schema-keeper<\/a><\/noindex> proporciona la funci\u00f3n <code>saveDump<\/code>, que guarda la estructura de todos los objetos de la base de datos como archivos de texto separados. Se crea un directorio que contiene la estructura de la base de datos, dividida en archivos agrupados que son f\u00e1ciles de agregar al VCS.<\/p>\n<p><\/p>\n<p>Consideremos la conversi\u00f3n de objetos de la base de datos a archivos a trav\u00e9s de varios ejemplos:<\/p>\n<p><\/p>\n<p>Tipo de objeto<br \/>\nEsquema<br \/>\nNombre<br \/>\nRuta relativa al archivo<\/p>\n<p>Tabla<br \/>\npublic<br \/>\naccounts<br \/>\n<code>.\/public\/tables\/accounts.txt<\/code><\/p>\n<p>Procedimiento almacenado<br \/>\npublic<br \/>\nauth(hash bigint)<br \/>\n<code>.\/public\/functions\/auth(int8).sql<\/code><\/p>\n<p>Representaci\u00f3n<br \/>\nbooking<br \/>\ntariffs<br \/>\n<code>.\/booking\/views\/tariffs.txt<\/code><\/p>\n<p><\/p>\n<p>El contenido de los archivos es una representaci\u00f3n textual de la estructura de un objeto de la base de datos en particular. Por ejemplo, para los procedimientos almacenados, el contenido del archivo ser\u00e1 la definici\u00f3n completa del procedimiento almacenado, que comienza con el bloque <code>CREATE OR REPLACE FUNCTION<\/code>.<\/p>\n<p><\/p>\n<p>Como se puede ver en la tabla anterior, la ruta al archivo contiene informaci\u00f3n sobre el tipo, el esquema y el nombre del objeto. Este enfoque facilita la navegaci\u00f3n por el volcado y la revisi\u00f3n del c\u00f3digo de los cambios en la base de datos.<\/p>\n<p><\/p>\n<blockquote><p>Extensi\u00f3n <code>.sql<\/code> para archivos con c\u00f3digo fuente de procedimientos almacenados, se seleccion\u00f3 para que el IDE proporcione autom\u00e1ticamente herramientas para interactuar con la base de datos al abrir el archivo.<\/p><\/blockquote>\n<p><\/p>\n<h2 id=\"kak-otslezhivat-izmeneniya-v-strukture-bd-posle-sohraneniya-dampa\">\u00bfC\u00f3mo rastrear cambios en la estructura de la base de datos despu\u00e9s de guardar el volcado?<\/h2>\n<p><\/p>\n<p>Al guardar el volcado de la estructura actual de la base de datos en VCS, obtenemos la posibilidad de verificar si se han realizado cambios en la estructura de la base de datos despu\u00e9s de crear el volcado. En la biblioteca <noindex><a rel=\"nofollow\" href=\"https:\/\/packagist.org\/packages\/schema-keeper\/schema-keeper\">schema-keeper<\/a><\/noindex> para identificar cambios en la estructura de la base de datos existe la funci\u00f3n <code>verifyDump<\/code>, que sin efectos secundarios devuelve informaci\u00f3n sobre las diferencias. <\/p>\n<p><\/p>\n<p>Un m\u00e9todo alternativo de verificaci\u00f3n es llamar nuevamente a la funci\u00f3n <code>saveDump<\/code>, especificando el mismo directorio, y verificar en VCS la existencia de cambios. Dado que todos los objetos de la base de datos se han guardado en archivos separados, VCS mostrar\u00e1 solo los objetos que han cambiado.<br \/>\nLa principal desventaja de este m\u00e9todo es la necesidad de sobrescribir archivos para ver los cambios.<\/p>\n<p><\/p>\n<h2 id=\"kak-perenosit-izmeneniya-v-strukture-bd-na-drugie-okruzheniya-bez-konfliktov-i-gigantskih-faylov-migraciy\">\u00bfC\u00f3mo trasladar los cambios en la estructura de la base de datos a otros entornos sin conflictos y con archivos de migraci\u00f3n reducidos?<\/h2>\n<p><\/p>\n<p>Gracias a la funci\u00f3n <code>deployDump<\/code> el c\u00f3digo fuente de los procedimientos almacenados puede ser editado exactamente igual que el c\u00f3digo fuente normal de la aplicaci\u00f3n. Se pueden agregar\/eliminar nuevas l\u00edneas en el c\u00f3digo de los procedimientos almacenados y enviar los cambios al sistema de control de versiones de inmediato, o crear\/eliminar procedimientos almacenados mediante la creaci\u00f3n\/eliminaci\u00f3n de los archivos correspondientes en el directorio del volcado. <\/p>\n<p><\/p>\n<p>Por ejemplo, para crear un nuevo procedimiento almacenado en el esquema <code>public<\/code> es suficiente crear un nuevo archivo con la extensi\u00f3n <code>.sql<\/code> en el directorio <code>public\/functions<\/code>, colocar en \u00e9l el c\u00f3digo fuente del procedimiento almacenado, incluyendo el bloque <code>CREATE OR REPLACE FUNCTION<\/code>, y luego llamar a la funci\u00f3n <code>deployDump<\/code>. De manera similar, se realiza la modificaci\u00f3n y eliminaci\u00f3n del procedimiento almacenado. De este modo, el c\u00f3digo llega tanto a VCS como a la base de datos. <\/p>\n<p><\/p>\n<p>Si en el c\u00f3digo fuente de alg\u00fan procedimiento almacenado aparece un error, o un desajuste entre el nombre del archivo y el procedimiento almacenado, entonces <code>deployDump<\/code> no se ejecutar\u00e1, mostrando el texto del error. La desincronizaci\u00f3n de los procedimientos almacenados entre el volcado y la base de datos actual es imposible al utilizar <code>deployDump<\/code>.<\/p>\n<p><\/p>\n<blockquote><p>Al crear un nuevo procedimiento almacenado, no es necesario introducir manualmente el nombre correcto del archivo. Basta con que el archivo tenga la extensi\u00f3n <code>.sql<\/code>. Despu\u00e9s de llamar a <code>deployDump<\/code> el texto del error contendr\u00e1 el nombre correcto, que se puede utilizar para renombrar el archivo.<\/p><\/blockquote>\n<p><code>deployDump<\/code> permite modificar los par\u00e1metros de la funci\u00f3n o el tipo de retorno sin acciones adicionales, mientras que en el enfoque cl\u00e1sico habr\u00eda que<br \/>\nprimero ejecutar <code>DROP FUNCTION<\/code>, y solo despu\u00e9s <code>CREATE OR REPLACE FUNCTION<\/code>.<\/p>\n<p><\/p>\n<p>Desafortunadamente, existen algunas situaciones en las que <code>deployDump<\/code> no se pueden aplicar los cambios autom\u00e1ticamente. Por ejemplo, si se elimina una funci\u00f3n desencadenante que est\u00e1 siendo utilizada por al menos un desencadenador. Estas situaciones se resuelven manualmente mediante archivos de migraci\u00f3n.<\/p>\n<p><\/p>\n<p>Si la transferencia de cambios en los procedimientos almacenados es responsabilidad del propio <noindex><a rel=\"nofollow\" href=\"https:\/\/packagist.org\/packages\/schema-keeper\/schema-keeper\">schema-keeper<\/a><\/noindex>, para transferir los dem\u00e1s cambios en la estructura es necesario utilizar archivos de migraci\u00f3n. Por ejemplo, una buena biblioteca para trabajar con migraciones es <noindex><a rel=\"nofollow\" href=\"https:\/\/packagist.org\/packages\/doctrine\/migrations\">doctrine\/migrations<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p>Las migraciones deben aplicarse antes de ejecutar <code>deployDump<\/code>. Esto permite hacer todos los cambios en la estructura y resolver situaciones problem\u00e1ticas, para que los cambios en los procedimientos almacenados se transfieran sin problemas posteriormente.<\/p>\n<p><\/p>\n<p>Trabajar con migraciones se describir\u00e1 m\u00e1s en los siguientes apartados.<\/p>\n<p><\/p>\n<h2 id=\"kak-naladit-process-parallelnoy-raboty-nad-proektom-neskolkih-razrabotchikov\">\u00bfC\u00f3mo establecer el proceso de trabajo paralelo en el proyecto entre varios desarrolladores?<\/h2>\n<p><\/p>\n<p>Es necesario crear un script de inicializaci\u00f3n completa de la base de datos, que ser\u00e1 ejecutado por el desarrollador en su m\u00e1quina de trabajo, alineando la estructura de la base de datos local con el volcado guardado en VCS. Lo m\u00e1s f\u00e1cil es dividir la inicializaci\u00f3n de la base de datos local en 3 pasos:<\/p>\n<p><\/p>\n<ol>\n<li>Importar el archivo con la estructura b\u00e1sica, que se llamar\u00e1, por ejemplo, <code>base.sql<\/code> <\/li>\n<li>Aplicaci\u00f3n de migraciones<\/li>\n<li>mountsnoop.py <code>deployDump<\/code><\/li>\n<\/ol>\n<p><\/p>\n<blockquote><p><code>base.sql<\/code> \u2014 este es el punto de partida, sobre el cual se aplican las migraciones y se ejecuta <code>deployDump<\/code>, es decir, el <code>base.sql + migraciones + deployDump = estructura actual de la base de datos<\/code>. Este archivo se puede generar utilizando la herramienta <code>pg_dump<\/code>. Se utiliza <code>base.sql<\/code> exclusivamente al inicializar la base de datos desde cero.<\/p><\/blockquote>\n<p>Llamaremos al script de inicializaci\u00f3n completa de la base de datos <code>refresh.sh<\/code>. El proceso de trabajo puede verse de la siguiente manera:<\/p>\n<p><\/p>\n<ol>\n<li>El desarrollador ejecuta en su entorno <code>refresh.sh<\/code> y obtiene la estructura actual de la base de datos<\/li>\n<li>El desarrollador comienza a trabajar en la tarea asignada, modificando la base de datos local para las necesidades de la nueva funcionalidad (<code>ALTER TABLE ... ADD COLUMN<\/code> etc.)<\/li>\n<li>Despu\u00e9s de completar la tarea, el desarrollador invoca la funci\u00f3n <code>saveDump<\/code>, para registrar en VCS los cambios realizados en la base de datos<\/li>\n<li>El desarrollador vuelve a ejecutar <code>refresh.sh<\/code>, luego <code>verifyDump<\/code>, que ahora muestra la lista de cambios para incluir en la migraci\u00f3n<\/li>\n<li>El desarrollador transfiere todos los cambios de estructura a un archivo de migraci\u00f3n, ejecuta una vez m\u00e1s <code>refresh.sh<\/code> y <code>verifyDump<\/code>, y, si la migraci\u00f3n se ha elaborado correctamente, <code>verifyDump<\/code> mostrar\u00e1 que no hay diferencias entre la base de datos local y el volcado guardado.<\/li>\n<\/ol>\n<p><\/p>\n<p>El proceso descrito anteriormente es compatible con los principios de gitflow. Cada rama en el VCS contendr\u00e1 su versi\u00f3n del volcado, y durante la fusi\u00f3n de ramas se realizar\u00e1 la fusi\u00f3n de volcadones. En la mayor\u00eda de los casos, despu\u00e9s de la fusi\u00f3n no es necesario tomar medidas adicionales, pero si se hicieron cambios en diferentes ramas, por ejemplo, en una misma tabla, puede surgir un conflicto.<\/p>\n<p><\/p>\n<p>Consideremos una situaci\u00f3n conflictiva con el siguiente ejemplo: hay una rama <em>develop<\/em>, de la cual se han ramificado dos ramas: <em>feature1<\/em> y <em>feature2<\/em>, que no tienen conflictos con <em>develop<\/em>, pero tienen conflictos entre s\u00ed. La tarea es realizar la fusi\u00f3n de ambas ramas en <em>develop<\/em>. Para tal caso, se recomienda primero fusionar una de las ramas en <em>develop<\/em>, y luego fusionar <em>develop<\/em> en la rama restante, resolviendo los conflictos en la \u00faltima rama, despu\u00e9s de lo cual se realizar\u00e1 la fusi\u00f3n de la \u00faltima rama en <em>develop<\/em>. En la etapa de resoluci\u00f3n de conflictos puede que sea necesario corregir el archivo de migraci\u00f3n en la \u00faltima rama, para que coincida con el volcado final, que incluye los resultados de las fusiones.<\/p>\n<p><\/p>\n<h2 id=\"kak-bezopasno-deploit-bolshee-kolichestvo-izmeneniy-v-strukture-bd-na-production-okruzhenie\">\u00bfC\u00f3mo desplegar de manera segura una mayor cantidad de cambios en la estructura de la base de datos en el entorno de producci\u00f3n?<\/h2>\n<p><\/p>\n<p>Gracias a la presencia de un volcado de la estructura actual de la base de datos en el VCS, surge la posibilidad de verificar la base de datos de producci\u00f3n para garantizar que coincide exactamente con la estructura requerida. Esto asegura que todos los cambios que los desarrolladores hab\u00edan pensado se han trasladado exitosamente a la base de datos de producci\u00f3n.<\/p>\n<p><\/p>\n<p>Dado que <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/current\/ddl.html\">DDL<\/a><\/noindex> en PostgreSQL es <noindex><a rel=\"nofollow\" href=\"https:\/\/wiki.postgresql.org\/wiki\/Transactional_DDL_in_PostgreSQL:_A_Competitive_Analysis\">transaccional<\/a><\/noindex>, se recomienda seguir el siguiente orden de despliegue, para que, en caso de un error imprevisto, se realice un <code>ROLLBACK<\/code>:<\/p>\n<p><\/p>\n<ol>\n<li>Iniciar la transacci\u00f3n<\/li>\n<li>En la transacci\u00f3n, realizar todas las migraciones<\/li>\n<li>En esta misma transacci\u00f3n, llevar a cabo <code>deployDump<\/code><\/li>\n<li>Sin finalizar la transacci\u00f3n, ejecutar <code>verifyDump<\/code>. Si no hay errores, ejecutar <code>COMMIT<\/code>. Si hay errores, ejecutar <code>ROLLBACK<\/code><\/li>\n<\/ol>\n<p><\/p>\n<p>Estos pasos se pueden integrar f\u00e1cilmente en los enfoques existentes para el despliegue de aplicaciones, incluyendo zero-downtime.<\/p>\n<p><\/p>\n<h1 id=\"zaklyuchenie\">Conclusi\u00f3n<\/h1>\n<p><\/p>\n<p>Gracias a los m\u00e9todos descritos anteriormente, se puede extraer el m\u00e1ximo rendimiento de los proyectos \"PHP + PostgreSQL\", sacrificando relativamente poco en t\u00e9rminos de comodidad de desarrollo en comparaci\u00f3n con la implementaci\u00f3n de toda la l\u00f3gica de negocio en el c\u00f3digo principal de la aplicaci\u00f3n. Adem\u00e1s, el procesamiento de datos en <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/current\/plpgsql.html\">PL\/pgSQL<\/a><\/noindex> a menudo se presenta de forma m\u00e1s transparente y requiere menos c\u00f3digo que la misma funcionalidad escrita en PHP.<\/p>\n<p>Fuente: <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\/es\/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=\"es_ES\" \/>\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\/es\/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\udd47L\u00f3gica empresarial en la base de datos con SchemaKeeper | ProHoster","description":"El objetivo de este art\u00edculo es mostrar, a trav\u00e9s de la biblioteca schema-keeper, herramientas que permiten de manera significativa.","canonical_url":"https:\/\/prohoster.info\/es\/blog\/administrirovanie\/biznes-logika-v-baze-dannyh-pri-pomoshhi-schemakeeper","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"es_ES","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\/es\/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\/es\/wp-json\/wp\/v2\/posts\/31385","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/comments?post=31385"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/posts\/31385\/revisions"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/media?parent=31385"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/categories?post=31385"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/tags?post=31385"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}