Llevo varios años trabajando con AWS y, si me preguntan cuál fue el servicio que más me costó "entender de verdad", sin dudarlo digo DynamoDB. No porque sea complicado de usar (de hecho crear una tabla toma como 30 segundos), sino porque viene uno con la cabeza llena de SQL y termina queriendo hacer cosas que en DynamoDB simplemente no se hacen así.
Este post es una introducción nivel 100. La idea es que si nunca has tocado DynamoDB, salgas con una imagen clara de qué es, cuándo conviene usarlo y, sobre todo, los conceptos mínimos para no pegarte contra la pared como me pasó a mí la primera vez.
¿Qué es DynamoDB? (la versión sin marketing)
DynamoDB es la base de datos NoSQL administrada de AWS. Punto. Es key-value y documental al mismo tiempo, serverless de verdad (no hay instancias que aprovisionar, no hay parches, no hay nada), y está diseñada para escalar a niveles que la mayoría de nosotros nunca vamos a necesitar.
Lo importante: no es un reemplazo de PostgreSQL ni de MySQL. Es otra cosa. Y ahí es donde mucha gente se confunde, yo el primero.
Cuando recién empecé con DynamoDB, intenté modelar una base como si fuera relacional. Tenía mi tabla de "usuarios", mi tabla de "pedidos", mi tabla de "productos"… y cuando quise hacer un join, bueno, no existe el join. Ahí me di cuenta que el problema no era el servicio, era cómo lo estaba pensando.
Cuándo sí, cuándo no
A ver, esto es lo primero que deberíamos preguntarnos antes de meter DynamoDB en cualquier arquitectura.
Tiene sentido cuando:
- Tu carga de trabajo es predominantemente por clave (lookups directos por ID).
- Necesitas latencias de un solo dígito en milisegundos, de forma consistente.
- Tienes patrones de acceso conocidos y bien definidos.
- Esperas escalar a volúmenes altos o tener picos impredecibles (un Black Friday, un lanzamiento, etc.).
- No quieres preocuparte por administrar la base.
Probablemente no es lo ideal cuando:
- Tus consultas son ad-hoc, exploratorias, tipo "quiero saber cuántos usuarios compraron X producto en marzo agrupado por ciudad".
- Necesitas joins complejos, agregaciones, reportes flexibles.
- Tu equipo no tiene tiempo o disposición para diseñar el modelo de datos pensando en los access patterns desde el inicio.
Para reportes y analítica, igual hay caminos (DynamoDB Streams hacia un data lake en S3, después Athena o Redshift), pero la fuente de verdad operacional puede vivir en DynamoDB sin problema.
Los conceptos mínimos que debes manejar
Tabla, item, atributo
Una tabla en DynamoDB tiene items (lo que en SQL serían filas) y cada item tiene atributos (las columnas, pero con la diferencia clave de que no todos los items tienen los mismos atributos). Esto último es importante: el schema es flexible. Puedes tener un item con 5 atributos y otro con 20 en la misma tabla.
La Primary Key (aquí se juega todo)
Aquí está el corazón de DynamoDB. Hay dos tipos:
- Partition Key sola: una sola clave que identifica de forma única al item.
- Partition Key + Sort Key (clave compuesta): dos claves. La combinación de ambas debe ser única.
La Partition Key define en qué partición física se guarda el dato. DynamoDB hashea ese valor y eso determina dónde vive el item. Por eso elegir bien la Partition Key es crítico: si todos tus items caen en la misma partición, vas a tener lo que se llama una "hot partition" y el rendimiento se degrada.
La Sort Key, cuando existe, te permite tener múltiples items con la misma Partition Key, ordenados. Y esto abre la puerta a patrones súper potentes que veremos más abajo.
Capacity: On-Demand vs Provisioned
DynamoDB cobra por lecturas y escrituras (RCUs y WCUs). Tienes dos modelos:
- On-Demand: pagas por lo que usas. Sin configuración. Ideal cuando no conoces el patrón de tráfico o cuando es muy variable.
- Provisioned: defines cuántas RCUs/WCUs quieres tener disponibles. Es más barato si tu carga es predecible y constante.
Mi regla práctica, y es mi opinión nada más: empieza siempre con On-Demand. Cuando tengas datos reales del consumo (después de unas semanas en producción), recién evalúa si te conviene cambiar a Provisioned con auto-scaling. Aquí me equivoqué la primera vez: provisioné capacidad "estimada" desde el día uno y terminé pagando por capacidad que nadie estaba usando. Ojo con eso.
Single-table design: el cambio mental que cuesta
Ya que mencioné que en DynamoDB no hay joins, la pregunta natural es: ¿cómo modelo entonces relaciones?
Hay dos escuelas. La primera es usar varias tablas, una por entidad, como en SQL. Funciona, no está mal, y para empezar es totalmente válido. La segunda es single-table design, donde metes todas tus entidades en una sola tabla y juegas con la Partition Key y la Sort Key para representar las relaciones.
Single-table es lo que recomienda Rick Houlihan (el creador de la práctica, ex-AWS) y la verdad es que es elegantísimo cuando lo dominas. Pero también es honesto decirlo: tiene una curva de aprendizaje empinada y si tu equipo recién está empezando con NoSQL, multi-tabla puede ser más sano para arrancar. En la práctica, es un trade-off entre eficiencia operacional y claridad para el equipo.
Un ejemplo rápido. Imagina que tienes Usuarios y Pedidos. En single-table podría verse así:
PK | SK | atributos
USER#123 | PROFILE | nombre, email, ciudad
USER#123 | ORDER#2024-001 | total, fecha, status
USER#123 | ORDER#2024-002 | total, fecha, status
USER#456 | PROFILE | nombre, email, ciudad
Con un solo Query a PK = USER#123 traes el perfil y todos sus pedidos en una operación. Eso, en SQL, serían dos queries o un join.
Query vs Scan (y por qué uno te puede arruinar la factura)
En DynamoDB hay dos formas básicas de leer múltiples items:
- Query: busca por Partition Key (y opcionalmente por Sort Key). Es eficiente. Le pagas solo por los items que devuelve.
- Scan: lee toda la tabla. Toda. Le pagas por leer cada item, te lo lleves o no.
Regla de oro: evita Scan en producción. Sirve para depuración o tareas administrativas puntuales, pero como parte del flujo normal de tu app es un error. Y aquí el ojo: parece inocente cuando tienes 10 mil items, pero el día que tengas 10 millones, el Scan se convierte en un problema serio (de costo y de latencia).
Si te ves obligado a hacer un Scan recurrente, casi siempre eso es una señal de que tu modelo de datos no contempló bien ese access pattern. Toca rediseñar, no insistir con el Scan.
GSI y LSI: cuando necesitas otra "vista"
Los Global Secondary Indexes (GSI) son básicamente una proyección de tu tabla con otra Partition Key y Sort Key. Los Local Secondary Indexes (LSI) comparten la Partition Key con la tabla principal pero cambian la Sort Key. Y solo se pueden crear cuando creas la tabla, importante esto.
En la mayoría de los casos prácticos vas a usar GSI. ¿Para qué? Para soportar otros patrones de acceso. Por ejemplo, si tu tabla está particionada por userId pero también necesitas consultar por email, creas un GSI con email como Partition Key y listo, ya tienes esa segunda forma de buscar.
Ojo aquí porque cada GSI tiene su propio costo de almacenamiento y de capacidad. No es gratis. He visto proyectos con 6 GSIs cuando con un buen diseño bastaban 2. Diseñar GSI debería partir de los access patterns reales, no de "por si acaso después necesitamos buscar por X".
Buenas prácticas que aprendí pegándome
Algunas cosas que me hubiera ahorrado dolor saber antes:
Define tus access patterns ANTES de crear la tabla. Sí, suena obvio. Pero la mayoría llegamos de SQL donde primero modelas las entidades y después haces los queries que necesites. En DynamoDB es al revés: primero listas todos los queries que tu app va a hacer, y a partir de eso diseñas la tabla. Si te saltas este paso, lo vas a pagar después con migraciones dolorosas.
TTL es tu amigo. DynamoDB tiene Time to Live nativo. Si tienes datos temporales (sesiones, tokens, caches), configurar TTL hace que DynamoDB borre esos items automáticamente, sin costo de escritura. Para esto, vale mucho la pena.
Cuidado con los items muy grandes. El límite por item es de 400KB. Si te acercas a eso, probablemente estás haciendo algo raro. Considera mover los blobs a S3 y guardar solo la referencia en DynamoDB.
Encripta y controla acceso desde el día uno. DynamoDB encripta en reposo por defecto (con KMS), eso ya viene de fábrica. Pero el control de acceso fino con IAM, eso sí lo tienes que diseñar. Usa roles específicos por aplicación, evita permisos dynamodb:* salvo en cuentas administrativas. Y si manejas datos sensibles, considera VPC endpoints para que el tráfico no salga a internet pública.
Streams + Lambda para reaccionar a cambios. DynamoDB Streams te permite procesar cada cambio (insert, update, delete) con una Lambda. Es la base para arquitecturas event-driven, sincronizar con OpenSearch, mantener auditoría, lo que se te ocurra. Súper potente y, honestamente, una de mis features favoritas del servicio.
Backups automáticos. Activa Point-in-Time Recovery (PITR). Es barato y te salva el día que alguien (tú, probablemente) borre lo que no debía.
Errores comunes que veo en la comunidad
En las charlas y meetups con la comunidad AWS, estos son los tropezones que más se repiten:
- Tratar a DynamoDB como SQL sin schema. Esto termina mal casi siempre. El modelo de datos en NoSQL se diseña diferente, no es opcional.
- Hacer Scans en flujos de producción. Funciona en dev, escala mal en prod.
- Crear demasiados GSI "por si acaso". Cada GSI cuesta. Diseña por access patterns reales.
- Pasar a Provisioned demasiado pronto. Sin datos de uso real, terminas estimando mal en cualquier dirección.
-
No pensar en hot partitions. Si tu Partition Key es algo como
countryy el 90% de tus usuarios son de un solo país, vas a tener problemas. Busca claves con buena cardinalidad.
DynamoDB no es ni mejor ni peor que una base relacional. Es una herramienta distinta, con sus fortalezas y sus trade-offs. Lo que sí puedo decir, después de varios proyectos productivos con ella, es que cuando se diseña bien, ofrece un nivel de performance, escalabilidad y simplicidad operativa que vale mucho la pena.
Si recién estás empezando, mi consejo es: arranca con un proyecto pequeño, fuérzate a definir los access patterns en papel antes de tocar la consola, y permítete equivocarte. La curva existe, pero una vez que pasas el primer mes peleándote con el modelo de datos, ya entendiste la filosofía y todo lo demás cae por su propio peso.
Si están en Ecuador y les interesa profundizar, dense una vuelta por nuestros eventos de la comunidad AWS. Ahí discutimos casos reales, decisiones de arquitectura y, sobre todo, las pifias que cometemos en el camino, que al final es donde más se aprende.
Nos leemos en el siguiente post, donde quiero entrar más a fondo a single-table design con un caso práctico. Cualquier comentario, duda o experiencia que quieran compartir, los leo abajo.
Top comments (0)