Saltar a contenido

ADR-001: Eleccion de Base de Datos Principal


Proposito

Ejemplo completo de un ADR para la decision de base de datos del Sistema de Reservas de Turnos Medicos.


Metadata

Campo Valor
ID ADR-001
Fecha 2025-02-10
Estado Accepted
Decisores Carlos Ramirez, Maria Lopez, DevOps Lead

Contexto

El Sistema de Reservas de Turnos Medicos necesita una base de datos para almacenar usuarios, medicos, clinicas, disponibilidad, y bookings. Los requisitos clave son:

  • Integridad transaccional: Las reservas no pueden tener conflictos (doble booking). Necesitamos ACID.
  • Consultas complejas: Buscar disponibilidad implica joins entre doctors, availability, blocked_dates, y bookings.
  • Volumen estimado: 50 clinicas, 500 medicos, 50,000 pacientes en el primer ano. ~200 bookings/dia inicialmente.
  • Presupuesto: Startup en etapa temprana, el costo de infraestructura debe ser bajo.
  • Equipo: 3 backend engineers, todos con experiencia en SQL. Uno tiene experiencia con MongoDB.
  • Regulacion: Datos de salud requieren encriptacion at-rest y audit trail.

Restricciones: - No tenemos DBA dedicado. - Usamos DigitalOcean como cloud provider. - Queremos managed service para reducir overhead operativo.


Opciones Consideradas

Opcion 1: PostgreSQL (Managed - DigitalOcean)

Pros: - ACID completo, ideal para transacciones de booking. - Soporte nativo para JSON (flexibilidad sin perder SQL). - Excelente soporte para concurrencia (MVCC, SELECT FOR UPDATE). - Managed service en DigitalOcean disponible y economico. - El equipo completo tiene experiencia con PostgreSQL. - Extensiones utiles: pgcrypto para encriptacion, pg_trgm para busqueda por nombre.

Contras: - Escalamiento horizontal mas complejo que NoSQL (read replicas si, sharding manual). - El plan mas barato de DO tiene solo 22 conexiones max.

Costo estimado: Bajo ($15/mes plan basico DO)

Opcion 2: MongoDB Atlas

Pros: - Schema flexible, rapido para iterar en etapa temprana. - Escalamiento horizontal nativo con sharding. - MongoDB Atlas tiene free tier generoso.

Contras: - No es ideal para transacciones multi-documento (bookings requieren consistencia fuerte). - Solo un miembro del equipo tiene experiencia. - Queries complejas con joins son mas complicadas (aggregation pipeline vs SQL joins). - Para garantizar no-doble-booking necesitamos distributed locks adicionales.

Costo estimado: Bajo (free tier) a Medio (si necesitamos transacciones multi-doc)

Opcion 3: MySQL (Managed - PlanetScale)

Pros: - ACID completo. - PlanetScale ofrece branching de BD (util para desarrollo). - Familiar para la mayoria de developers.

Contras: - Menos features avanzadas que PostgreSQL (sin JSON nativo robusto, sin arrays, sin extensiones). - PlanetScale elimino free tier. - El equipo tiene mas experiencia con PostgreSQL. - No disponible como managed en DigitalOcean (agrega otro proveedor).

Costo estimado: Medio ($29/mes PlanetScale Scaler)


Decision

Opcion elegida: PostgreSQL (Managed - DigitalOcean)

Razon principal: PostgreSQL ofrece la mejor combinacion de integridad transaccional (critica para bookings), familiaridad del equipo, costo, y compatibilidad con nuestra infraestructura existente en DigitalOcean.

Razonamiento detallado: - El dominio de reservas requiere consistencia fuerte. Un doble booking es inaceptable. PostgreSQL con SELECT FOR UPDATE resuelve esto nativamente. - Todo el equipo sabe SQL y PostgreSQL. Con MongoDB perderiamos velocidad de desarrollo. - DigitalOcean managed PostgreSQL nos da backups automaticos, encriptacion at-rest, y failover sin necesidad de DBA. - El volumen esperado (200 bookings/dia) esta muy por debajo de los limites de una instancia PostgreSQL basica.

Reconsiderariamos si: El volumen supera 10,000 bookings/dia y necesitamos escalamiento horizontal agresivo, o si agregamos features de busqueda full-text que justifiquen Elasticsearch como complemento.


Consecuencias

Positivas

  • Integridad garantizada para transacciones de booking.
  • Desarrollo rapido por familiaridad del equipo.
  • Un solo proveedor (DigitalOcean) para compute y BD.
  • Managed service reduce carga operativa.

Negativas

  • Limitados a 22 conexiones en plan basico (requiere connection pooling con PgBouncer).
  • Escalamiento horizontal futuro requerira mas trabajo que con MongoDB.
  • Dependencia de DigitalOcean como proveedor de BD.

Neutras

  • Necesitaremos PgBouncer cuando tengamos mas de 2-3 instancias de aplicacion.
  • Migraciones de schema deben gestionarse con herramienta dedicada (TypeORM migrations).

Plan de Implementacion

  1. Provisionar instancia PostgreSQL 17 managed en DO (plan 1GB, NYC3).
  2. Configurar encriptacion at-rest y SSL para conexiones.
  3. Implementar esquema inicial con migraciones de TypeORM.
  4. Configurar PgBouncer en transaction mode para manejar connection pooling.
  5. Establecer backup diario y política de retencion de 7 dias.
  6. Crear runbook para escenarios de fallo de BD.

Referencias


Checklist de Completitud

  • Contexto documentado con hechos
  • Al menos 2 opciones evaluadas
  • Decision justificada con razonamiento
  • Consecuencias positivas y negativas listadas
  • Revisada por otro ingeniero
  • Derivados generados (cambios en system-design / infraestructura)

Archivos relacionados