Ir al contenido

Desarrollo de software a medida

Software a medida con Laravel y PostgreSQL

Lo que PostgreSQL da a una construcción con Laravel y MySQL no - una migración que se revierte al fallar, garantías que Eloquent no puede sortear, e informes sin una segunda base de datos.

Laravel funciona con las dos, así que elegir PostgreSQL es una decisión y no un valor por defecto - y conviene ser concreto sobre lo que aporta, porque las comparaciones disponibles hablan de benchmarks y casi ninguna de lo que pasa de verdad un jueves por la tarde durante un despliegue.

Una migración de Laravel fallida se revierte

Esta es la diferencia que cambia el comportamiento de un equipo, y es la que rara vez se menciona.

PostgreSQL aplica los cambios de esquema de forma transaccional. Una migración de seis sentencias que falla en la cuarta deja la base de datos exactamente como estaba. Nada a medias, nada que desenredar, y la migración se puede corregir y volver a ejecutar.

MySQL no. Las tres primeras sentencias quedan aplicadas, la migración se registra como no ejecutada, y ahora alguien tiene que establecer a mano qué mitad existe. En producción, con prisa, con el despliegue a medio terminar.

La consecuencia es cultural antes que técnica. Donde una migración fallida es recuperable, las migraciones se escriben como deberían: pequeñas, concretas, revisadas. Donde una migración fallida es un incidente, se agrupan, se posponen y al final se aplican a mano. Así los esquemas se salen del control de versiones, y es el estado en el que encontramos más a menudo los proyectos heredados. La lectura relacionada es la migración que tiró el sitio.

Restricciones que Eloquent no puede sortear

Una regla impuesta en un modelo se cumple para el código que pasa por el modelo.

No se cumple para una actualización masiva. No se cumple para una llamada del query builder que escribe directamente en la tabla, que toda base de código tiene en algún sitio. No se cumple para el comando de consola que alguien escribió a las nueve de la noche para arreglar un problema de datos, ni para la importación que corre una vez al trimestre y nunca se revisó.

Impuesto por debajo de la aplicación, se cumple en todos los casos. Un índice único resuelve dos peticiones simultáneas por el mismo registro, algo que comprobar antes nunca consigue: la comprobación y el insert son sentencias separadas y el hueco entre ellas es donde aparece el duplicado. Una clave ajena hace imposible una fila huérfana en vez de improbable. Una restricción de comprobación mantiene una cantidad positiva en la fila, no solo en el formulario que la validó la última vez.

PostgreSQL añade dos que importan en la práctica. Una restricción de exclusión rechaza una reserva cuyo rango de fechas se solapa con otra existente del mismo recurso, cerrando una condición de carrera genuinamente difícil de cerrar en PHP. Y un índice parcial cubre solo las filas que merecen cobertura, para que una consulta sobre pedidos abiertos no pague el coste de cinco años de cerrados.

JSONB, y dónde debe empezar la columna

Algunos datos no tienen esquema que diseñar. Una carga de un proveedor que la altera sin avisar. Ajustes por inquilino. Un formulario que construye el propio cliente.

PostgreSQL lo trata bien y no a disgusto: JSONB se almacena de forma compacta, se consulta con operadores reales, se indexa con GIN y se castea limpiamente a un atributo de Eloquent. Es una decisión de diseño razonable, no una retirada.

El declive es gradual y siempre es la misma historia. Añadir una clave a JSON no necesita migración ni atrae revisión, así que ahí empiezan a ir los campos. Al segundo año nadie puede responder una pregunta sobre los datos sin leer PHP, y sacar un campo a una columna significa escribir una migración que recorra tres años de filas con formas inconsistentes.

La prueba que lo evita: si alguna vez vas a filtrar, ordenar, unir o informar por ello, es una columna. Todo lo demás puede vivir en JSONB, y debería.

Informes sin una segunda base de datos

Muchísimas aplicaciones Laravel se traen miles de filas a PHP y las recorren para producir una cifra, porque la consulta que lo haría en SQL parecía desconocida.

Las funciones de ventana convierten totales acumulados, rankings y comparaciones entre periodos en una sola consulta. Las expresiones de tabla común hacen legible un cálculo de varios pasos en vez de anidado. Los lateral joins resuelven la forma de los tres primeros por cliente, que si no se convierte en un bucle N+1. Cada una de ellas sustituye una página de código por una consulta que la base de datos ejecuta en una pasada.

Apuntadas a una réplica de lectura, esos informes se quedan completamente fuera de la carga transaccional. Un almacén aparte es una respuesta real cuando los informes compiten de verdad con producción o abarcan varios sistemas, pero eso debería seguir a una medición y no precederla, y la mayoría de las aplicaciones llegan ahí más tarde de lo que esperan. Ingeniería de base de datos y Eloquent es donde está este trabajo.

Qué cambia de verdad en Eloquent

Honestos con la fricción, porque hay algo.

La comparación de cadenas distingue mayúsculas, así que un where sobre un correo o una referencia que funcionaba en MySQL puede dejar de coincidir. LIKE distingue mayúsculas e ILIKE es la forma que no, y eso no es portable: una consulta escrita para una base de datos necesita atención en la otra.

Las comparaciones son estrictas de tipo. Pasar una cadena donde la columna es un entero da un error en vez de convertir en silencio, que es el comportamiento mejor y aparecerá en el código que dependía de la conversión.

Las claves autoincrementales usan secuencias, lo que importa al sembrar datos con identificadores explícitos y al copiar filas entre entornos. Y todo lo escrito como SQL en bruto es ahora específico de la base de datos, que es un argumento para mantener el SQL en bruto en pocos sitios con nombre en vez de repartido por los modelos.

Ninguna de estas cosas es un obstáculo. Todas son más baratas de conocer en la semana uno que de descubrir en una suite de pruebas que pasa en local y falla en staging.

La forma del trabajo con Laravel y PostgreSQL, y dónde encaja el esquema

En la primera fase, a propósito, junto al flujo alrededor del cual se construye, no en un documento de diseño que la precede ni en una revisión que la sigue.

Cuatro decisiones merecen nombrarse porque, si se posponen, se convierten en migraciones por todas las tablas relacionadas. El conjunto de restricciones y qué hace imposible cada una. La frontera entre una columna y JSONB. Cómo se comportará un cambio de esquema contra una tabla que acabará con cuarenta millones de filas, lo que decide si un índice se crea de forma concurrente o con un bloqueo que nadie presupuestó. Y si los informes leen de una réplica, porque retrofitarlo significa auditar cada consulta para ver qué conexión usó.

El resto del proyecto está estructurado como en la página de software a medida: por fases, cada una acordada por escrito, cada una acabando con algo desplegado.

Qué recibes con un proyecto de Laravel y PostgreSQL

Más allá de la aplicación y su repositorio, las cosas propias de esta elección.

Las migraciones, que son el historial de la base de datos y el motivo de que un cambio de esquema se pueda revisar como cualquier otro código. Una nota sobre el modelo de datos que explique la forma en vez de repetirla. Un inventario de índices que diga para qué consulta existe cada uno, de modo que un futuro desarrollador que quite uno sepa qué se va a volver lento. Las restricciones anotadas con lo que evitan. Y las consultas de informes escritas y explicadas: una función de ventana que nadie entiende es una que se sustituirá por un bucle en PHP la primera vez que haya que cambiarla.

Cuándo MySQL es la mejor respuesta

Si tu hosting, tu equipo de operaciones o la política de tu cliente está construida alrededor de MySQL, eso es una restricción real y no una deficiencia técnica. Un equipo que sabe restaurar, monitorizar y ajustar una base de datos vale más que un conjunto de características marginalmente mejor en otra que nadie ha operado.

Si una aplicación existente ya está en MySQL y está sana, migrarla por las características de arriba rara vez compensa la interrupción por sí sola. Hazlo cuando haya otro motivo para tocar la capa de datos.

Y si la aplicación es pequeña, de lectura mayoritaria y el esquema está asentado, la diferencia entre las dos no será lo que decida si el proyecto sale bien.

Alcance y condiciones

Modelo de colaboración
Alcance cerrado, acordado por escrito antes de empezar. No es una tarifa por día contra una lista abierta.
Precio y plazo
Los dos se fijan por proyecto, una vez fijado el alcance. Se ofertan juntos, antes de construir nada.
Qué necesitamos de usted
Una persona que pueda aprobar decisiones, y acceso a su repositorio y a su gestor de incidencias.
No incluido
Todo lo que quede fuera del alcance acordado. Pasa a ser su propio alcance, no una modificación.
Costes de terceros
El alojamiento, las licencias, las tarifas de API y las suscripciones SaaS los contrata y paga usted.
Facturación
Codefacture Yazılım A.Ş., Türkiye. EUR, USD o GBP por transferencia, sin IVA turco en servicios exportados.

Preguntas frecuentes

¿Cuál es la mayor diferencia práctica con MySQL?
Una migración fallida no deja nada detrás. PostgreSQL aplica los cambios de esquema dentro de una transacción, así que una migración que falla en su cuarta sentencia revierte las tres primeras y la base de datos queda exactamente como estaba. En MySQL las tres primeras quedan aplicadas, la migración se registra como no ejecutada, y alguien tiene que averiguar a mano qué mitad ocurrió - normalmente un viernes, normalmente en producción. Esa única propiedad cambia la confianza con la que un equipo despliega.
¿Puede Eloquent sortear una restricción de base de datos?
Una de base de datos no, y por eso está ahí. La validación en el modelo, los observers y los eventos los sortea una actualización masiva, una llamada del query builder que salta el modelo, y cualquier comando de consola escrito con prisa. Un índice único, una clave ajena o una restricción de comprobación resisten frente a todo eso porque se imponen por debajo de la aplicación. En un sistema que maneja dinero o stock, la diferencia es entre un fallo que no puede ocurrir y uno que aún no ha ocurrido.
¿JSONB es una excusa para no diseñar un esquema?
No, y la trampa es lo bastante real como para nombrarla. JSONB es genuinamente útil para datos cuya forma no controlas - la carga de un webhook, ajustes por inquilino, un formulario que configura el cliente - y con un índice GIN se consulta bien en vez de ser una columna de solo escritura. Lo que no debe convertirse es en el sitio al que van los campos nuevos porque una migración daba trabajo. La prueba es sencilla: si alguna vez vas a filtrar, ordenar, unir o informar por ello, es una columna.
¿Necesitamos una base de datos de informes aparte?
Normalmente no, y es una cosa menos que sincronizar y operar. Las funciones de ventana, las expresiones de tabla común y los lateral joins permiten que una consulta haga en la base de datos lo que las aplicaciones hacen trayéndose miles de filas a PHP y recorriéndolas. Apuntadas a una réplica de lectura, se mantienen lejos de la carga transaccional. Un almacén aparte se gana su sitio cuando los informes compiten de verdad con producción o abarcan varios sistemas, y eso es una medición, no una suposición.
¿Leemos esto en vez de vuestra página de software a medida o además de ella?
Además. Esa página trata de cómo se acota, se lleva y se entrega una construcción; esta trata solo de lo que cambia la elección de base de datos, porque quien busca un equipo de Laravel y PostgreSQL quiere esa pregunta respondida y no la general. Nada del arreglo comercial cambia.
Llamar+1 848 272 7583WhatsApp+90 850 308 5436Correoinfo@codefacture.comPágina de contacto