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¶
- Provisionar instancia PostgreSQL 17 managed en DO (plan 1GB, NYC3).
- Configurar encriptacion at-rest y SSL para conexiones.
- Implementar esquema inicial con migraciones de TypeORM.
- Configurar PgBouncer en transaction mode para manejar connection pooling.
- Establecer backup diario y política de retencion de 7 dias.
- Crear runbook para escenarios de fallo de BD.
Referencias¶
- DigitalOcean Managed PostgreSQL - Pricing
- PostgreSQL vs MongoDB for transactional workloads
- HIPAA compliance considerations for managed databases
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¶
- _template.adr.md - Plantilla de ADR
- adr-002-api-style.md - Decision de estilo de API
- system-design.md - Diseno del sistema
- ../07-devops-and-platform/infrastructure-as-code.md - Infraestructura