Creación de un SaaS multicliente: base de datos por cliente frente a esquema compartido
La decisión arquitectónica más importante en el desarrollo de SaaS: cómo aislar los datos de los clientes. Comparamos tres enfoques con análisis de costes reales, estrategias de migración y ejemplos de código.
La decisión que lo determina todo
A la hora de desarrollar un producto SaaS, la decisión arquitectónica más importante es el aislamiento de los clientes. Si te equivocas, acabarás dedicando meses a la migración más adelante. Existen tres enfoques, cada uno con sus claras ventajas e inconvenientes:
Enfoque 1: Base de datos compartida, esquema compartido (aislamiento a nivel de fila)
Los datos de todos los clientes se almacenan en las mismas tablas, diferenciados por una columna «tenant_id». Este es el método más sencillo y económico.
# Django: filtrado automático de inquilinos con middleware
class TenantMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
# Establecer el inquilino a partir del JWT o del subdominio
request.tenant = get_tenant_from_request(request)
return self.get_response(request)
class TenantManager(models.Manager):
def get_queryset(self):
from threading import local
_thread_locals = local()
tenant = getattr(_thread_locals, 'tenant', None)
qs = super().get_queryset()
if tenant:
qs = qs.filter(tenant_id=tenant.id)
return
qsclass Order(models.Model):
tenant = models.ForeignKey('Tenant', on_delete=models.CASCADE)
# ... otros campos
objects = TenantManager() # Todas las consultas se filtran automáticamenteVentajas: Sencillo, económico (entre 50 y 200 dólares al mes por una base de datos), fácil de implementar, grupo de conexiones compartido. Desventajas: Riesgo de fugas de datos si se olvida aplicar un filtro, problema de «vecinos ruidosos» (las consultas pesadas de un usuario afectan a los demás), mayor dificultad para cumplir con la normativa (eliminación de datos según el RGPD).
Enfoque 2: Base de datos compartida, esquemas independientes (esquemas de PostgreSQL)
Cada usuario dispone de su propio esquema de PostgreSQL dentro de una misma base de datos. Las tablas son idénticas, pero están aisladas por espacio de nombres.
# Uso de la biblioteca django-tenants#
Cada solicitud establece el esquema en función del
subdominio# settings.
pyDATABASE_ROUTERS = ['django_tenants.routers.TenantSyncRouter']
# El middleware establece el esquema para cada
solicitud# acme.yourapp.com -> esquema
«acme»# globex.yourapp.com -> esquema
«globex»# Equivalente en SQL:
# SET search_path TO 'acme'; -- ahora todas las consultas se dirigen a las tablas de
acme# SELECT * FROM orders; -- devuelve solo los pedidos de acmeVentajas: Aislamiento sólido sin bases de datos adicionales, fácil eliminación de datos (DROP SCHEMA CASCADE), Ãndices independientes por cliente. Desventajas: Complejidad de la migración (hay que migrar todos los esquemas), la gestión de la piscina de conexiones es más complicada, máximo de unos 500 clientes antes de que el rendimiento se vea afectado.
Enfoque 3: Una base de datos por cliente
Cada cliente dispone de su propia base de datos. Máximo aislamiento, máxima complejidad operativa.
Ventajas: Aislamiento total, escalabilidad independiente, fácil cumplimiento normativo, posibilidad de ofrecer infraestructura dedicada a clientes empresariales. Desventajas: Caro (entre 50 y 200 dólares al mes por inquilino), la gestión de grupos de conexiones es una pesadilla, las migraciones abarcan cientos de bases de datos y el análisis entre inquilinos requiere un almacén de datos.
Matriz de decisión: ¿qué enfoque elegir?
| Factor | Esquema compartido | Esquemas independientes | Bases de datos independientes |
|---|---|---|---|
| Coste mensual (100 inquilinos) | entre 100 y 200 dólares | entre 200 y 500 dólares | entre 5.000 y 20.000 dólares |
| LÃmite del número de inquilinos | Ilimitado | ~500 | ~100 (dominable) |
| Aislamiento de datos | Débil (a nivel de fila) | Fuerte (a nivel de esquema) | Completo |
| Cumplimiento normativo (RGPD/SOC 2) | DifÃcil | Moderado | Fácil |
| Riesgo de tener vecinos ruidosos | Alto | Medio | Ninguno |
| Ideal para | B2C, SaaS para pymes | SaaS para el mercado medio | SaaS para empresas |
Nuestra recomendación: Empieza con Shared y luego pasa a un plan superior
Empieza con un esquema compartido y aislamiento a nivel de fila. Asà podrás lanzar el producto al mercado rápidamente y cubrirás el 90 % de los casos de uso. Cuando consigas clientes empresariales que necesiten garantÃas de aislamiento, ofréceles esquemas o bases de datos independientes como nivel premium.
La clave está en diseñar tus modelos con un tenant_id desde el primer momento. Esto permite migrar posteriormente a cualquier enfoque sin tener que reescribir la aplicación.
La mejor arquitectura multitenant es aquella que se adapta a tu situación actual. Una startup con 10 clientes que utiliza una base de datos por cliente está pagando 10 veces más de lo que deberÃa.
— alokknight IngenierÃa
