SQLite es el defecto de Laravel. ¿Cuándo basta?
El valor por defecto cambió y muchas aplicaciones llegaron a producción con él sin que nadie lo decidiera. Los casos en que eso es correcto son reales y más estrechos de lo que sugiere.
La base de datos por defecto de Laravel es SQLite, y los valores por defecto son poderosos. Un número nada pequeño de aplicaciones llega hoy a producción con él porque nadie cambió la línea, no porque alguien decidiera que era lo adecuado.
A veces lo es. Aquí es donde cae la línea de verdad.
Qué es genuinamente distinto
No el SQL. No Eloquent, que se comporta igual. Una cosa: SQLite es un fichero que su proceso abre, no un servidor al que su proceso se conecta.
Todo se sigue de ahí. No hay límite de conexiones porque no hay conexiones. No hay latencia de red porque no hay red. Y las escrituras se serializan entre todos los procesos que tocan el fichero, porque un fichero no tiene planificador que arbitre entre clientes.
Active WAL antes que nada. Sin él, un lector bloquea a un escritor y un escritor bloquea a los lectores, que es la configuración que la mayoría mide sin saberlo:
// una migración, o un service provider
DB::statement('PRAGMA journal_mode = WAL');
DB::statement('PRAGMA busy_timeout = 5000');
DB::statement('PRAGMA foreign_keys = ON');Esas tres son casi obligatorias. WAL deja avanzar a los lectores durante una
escritura. El tiempo de espera convierte un error instantáneo de database is locked en una espera corta, que es casi siempre lo que quería. Y las claves
foráneas están desactivadas por defecto en SQLite, lo cual sorprende a quien
escribió constrained() en una migración y dio por hecho que se estaba
imponiendo.
Dónde es la respuesta correcta
Una herramienta interna. Veinte personas, sobre todo leyendo. El ahorro operativo es real: ningún servidor de base de datos que parchear, respaldar, asegurar o pagar, y una copia de seguridad es copiar un fichero.
Una aplicación en un solo servidor con escrituras moderadas. Un sitio de contenido, una página de reservas, un SaaS pequeño en su primer año. SQLite en disco local es más rápido que Postgres por red para un solo lector, porque no cruza un socket.
Las pruebas. Una base SQLite en memoria hace rápida una batería, con la advertencia de más abajo.
Cualquier cosa embebida o desplegada en el borde, donde no hay servidor de base de datos disponible.
Dónde no lo es
Varios servidores de aplicación. Este es el límite duro. Dos servidores web no pueden compartir con seguridad un fichero SQLite sobre un sistema de ficheros de red. Si alguna vez va a escalar horizontalmente, esta decisión hay que tomarla otra vez, y tomarla después es una migración bajo presión.
Trabajo con muchas escrituras. Cualquier cosa que registre cada petición, ingiera eventos o procese una cola en la base de datos. Las escrituras se serializan; eso es el diseño, no un problema de ajuste.
Más de un par de workers de cola. Los workers que consultan una tabla de trabajos son escritores concurrentes. Use Redis para la cola y SQLite para la aplicación, o ejecute un worker y acepte el rendimiento.
Cualquier cosa que necesite recuperación a un punto en el tiempo, replicación o una réplica de lectura. Hay herramientas que añaden replicación sobre SQLite y son una dependencia y una decisión, no un valor por defecto.
La trampa de las pruebas
La decisión sobre SQLite más común en una base de código Laravel no es la de
producción. Es :memory: en phpunit.xml, elegida por velocidad, contra una
aplicación que ejecuta MySQL o Postgres.
Esa batería no puede cazar:
- Una violación de restricción que el motor real impone y SQLite no.
- Una diferencia de colación, que es la trampa de las mayúsculas con otro sombrero.
- Una migración que bloquea una tabla grande, porque no hay bloqueo ni tabla.
- Cualquier cosa que use un operador JSON, una función de ventana o un tipo que el motor real tiene y SQLite no.
Es un intercambio razonable para una batería con mucha prueba unitaria y malo como única cosa entre usted y un error de esquema. Ejecute la batería rápida en SQLite si quiere; ejecute la batería que da paso a un despliegue contra el motor al que despliega.
Decidir con honestidad
Hágase una pregunta: ¿va a correr esta aplicación alguna vez en más de un servidor?
Si la respuesta es no y sabe por qué es no - es interna, tiene un techo, es de verdad pequeña - SQLite no es un compromiso. Es menos infraestructura que poseer, y poseer menos infraestructura es un beneficio real que se descarta con demasiada facilidad.
Si la respuesta es sí, o es "probablemente no pero quién sabe", empiece en el motor en el que acabaría. Migrar una aplicación en marcha es trabajo que se evita por completo dedicando diez minutos a esto en la primera semana, que es el mismo argumento que el dinero y las fechas, y se sostiene por la misma razón.
