Curso exprés · No. 06

Los lenguajes y los frameworks van y vienen. Los datos que guardás, y la forma en que los guardás, pueden sobrevivirlos a todos — así que elegir una base de datos es elegir cómo recuerda tu sistema, y qué tan difícil es hacerle cambiar de opinión.

Solo la esencia · Una imagen por almacén · Ejemplos antes que benchmarks

§ 01

Una base de datos es la memoria de largo plazo de tu sistema. El código se reescribe; los datos, y la forma que elegiste para ellos, suelen sobrevivir a todo lo que los rodea.

Los datos sobreviven al código

Una casa se repinta, se reamuebla, hasta se le rehace el techo a lo largo de décadas — pero los cimientos que se vertieron el primer día se quedan, porque reemplazarlos significa levantar la casa entera.

Los lenguajes cambian, los frameworks se intercambian, la UI se redibuja diez veces. Los datos y su estructura normalmente se quedan, porque cambiarlos en un sistema vivo lleno de registros reales es lento y riesgoso. Así que la base de datos es lo primero en lo que hay que pensar a fondo, y lo último que conviene apurar.

Una base de datos responde dos preguntas

Elegir dónde guardar las cosas plantea dos cuestiones: qué forma tienen las cosas — libros en estantes, o herramientas raras en ganchos? — y qué tan seguras deben estar — una bóveda, o un cajón a mano?

Todo almacén se define por cómo le da forma a los datos (tablas rígidas, documentos flexibles, un grafo de enlaces) y qué garantiza (corrección estricta, o velocidad y disponibilidad con promesas más laxas). Casi toda elección de base de datos es una respuesta distinta a esas dos — y el resto de este curso es el menú.

Elegí por cómo leés y escribís, no por la moda

Un archivador, un fichero de catálogo y una cinta transportadora son todos «almacenamiento» — pero elegís por cómo vas a buscar las cosas, no por cuál parece más nuevo.

No hay una mejor base de datos. Un almacén perfecto para búsquedas rápidas por clave es el equivocado para consultas de relaciones profundas; uno construido para escrituras enormes es el equivocado para transacciones bancarias estrictas. La pregunta correcta es tu patrón de acceso — qué leés, qué escribís, con qué frecuencia, y cómo debe comportarse cuando las cosas salen mal.

El código es fácil de cambiar. Los datos no. Elegí el almacén como una decisión con la que vas a vivir durante años — porque así será.

§ 02

Para la mayoría de los sistemas el default es la base de datos relacional — y se gana ese default. Empezá acá, y salí solo con una razón.

Tablas, filas y relaciones

Una hoja de cálculo bien hecha: cada hoja es un tipo de cosa (clientes, pedidos), cada fila un registro, y los pedidos apuntan de vuelta al cliente al que pertenecen.

Las bases de datos relacionales (Postgres, MySQL) guardan los datos en tablas con un esquema fijo, y enlazan tablas por referencia — una fila de pedido contiene el id de su cliente. El esquema es una promesa sobre la forma: cada pedido tiene las columnas que debería, verificadas al entrar. Estructura por adelantado, a cambio de cordura más tarde.

ACID: corrección de todo o nada

Una transferencia de dinero son dos escrituras — menos acá, más allá — pero una sola intención. O pasan las dos o ninguna; una transferencia a medias es un desastre.

Las bases de datos relacionales dan transacciones con garantías ACID: un grupo de cambios se confirma por completo o se revierte por completo, aislado de los demás, y sobrevive a una caída una vez confirmado. Por eso bancos, pedidos e inventarios viven en SQL — cuando la corrección importa más que la velocidad cruda, querés esta promesa.

SQL: pedí lo que querés, no cómo conseguirlo

Le decís a un bibliotecario «cada novela de autores franceses publicada después de 1950, ordenada por año» — y él se las arregla para encontrarlas. Describís el resultado, no la búsqueda.

SQL es un lenguaje de consultas declarativo: enunciás la respuesta que querés y la base de datos planifica cómo obtenerla, incluyendo unir tablas entre sí. SELECT ... JOIN ... WHERE ... puede responder preguntas que nunca anticipaste al momento de diseñar — uno de los superpoderes silenciosos del modelo relacional.

Por qué es el default correcto

Una buena herramienta de propósito general: no la más rápida en ningún trabajo concreto, pero la que agarrás hasta que un trabajo específicamente exija otra cosa.

Datos estructurados, relaciones reales, consultas ad-hoc, garantías fuertes — la base de datos relacional hace todo eso bien, y el Postgres moderno además maneja JSON, búsqueda full-text e incluso vectores. Empezá cada proyecto acá; echá mano de otra cosa solo cuando un dolor concreto — escala, forma o patrón de acceso — te empuje afuera.

Empezá con Postgres. La pregunta no es «por qué SQL» — es si tenés una razón real para no usarlo.

§ 03

A veces la tabla rígida es la forma equivocada. «NoSQL» es en realidad una familia de almacenes, cada uno doblando las reglas en una dirección distinta para un trabajo distinto.

Almacenes documentales: un blob JSON por cosa

Una carpeta de formularios completados, donde cada formulario puede tener campos ligeramente distintos — sin una plantilla central que obligue a todos a coincidir.

Las bases de datos documentales (MongoDB) guardan registros como documentos tipo JSON flexibles, anidados y con poco esquema, de modo que dos registros en una misma colección pueden diferir. Geniales cuando las formas varían o evolucionan rápido, y una cosa entera — un producto, un perfil — vive como un único documento que traés en una sola lectura. El costo: menos garantías y consultas entre documentos más difíciles que en SQL.

Almacenes clave-valor: un hash map gigante

Un guardarropa — entregás un número de ticket, te devuelven exactamente tu abrigo. Sin buscar, sin preguntas, al instante.

Los almacenes clave-valor (Redis, DynamoDB) son la forma más simple: una clave entra, un valor sale, vertiginosamente rápido. Perfectos para caching, sesiones, contadores de rate-limit, y cualquier cosa que traés por un id conocido. El trueque: solo podés buscar cosas por clave — no hay consultas ricas sobre los valores en sí.

Almacenes wide-column: hechos para escrituras enormes

Un almacén vasto con pasillos idénticos sin fin, dispuestos de modo que mil autoelevadores puedan abastecer estantes a la vez sin chocar entre sí.

Los almacenes wide-column (Cassandra) reparten datos por muchas máquinas para throughput de escritura masivo y escala, cambiando consultas ricas y consistencia estricta por la capacidad de absorber una manguera de incendios. Se usan para logs de eventos, telemetría y feeds a la escala donde una sola caja SQL se doblaría. Potentes — y más trabajo operativo para correr bien.

Bases de datos de grafos: cuando los enlaces son el punto

El pizarrón de un detective — fotos conectadas por hilo. El valor no está en ninguna foto; está en la red de quién está atado a quién.

Las bases de datos de grafos (Neo4j) modelan los datos como nodos y las aristas entre ellos, haciendo que las consultas de relaciones — «amigos de amigos a quienes les gusta esto», «el camino entre estas dos cuentas» — sean naturales y rápidas, donde SQL necesitaría joins dolorosos de muchas vías. El hogar de los grafos sociales, las recomendaciones y la detección de fraude. Echá mano de ella cuando las conexiones importan más que los registros.

NoSQL no es «SQL más nuevo». Cada almacén deja caer una garantía para ganar algo específico — sabé cuál estás canjeando.

§ 04

Más allá de los almacenes generales se sientan bases de datos construidas para un solo trabajo, donde un motor hecho a medida le gana a uno general por lejos.

Time-series: datos sellados por el reloj

La cinta de un monitor de ritmo cardíaco — una tira sin fin de lecturas, cada una atada a un instante, donde casi siempre preguntás «¿qué pasó entre estos dos momentos?»

Las bases de datos time-series (InfluxDB, TimescaleDB) están afinadas para datos que llegan en orden temporal y se consultan por tiempo — métricas, lecturas de sensores, precios. Ingestan streams enormes y responden «promedio por minuto durante la última semana» rápido, con expiración incorporada de datos viejos. Cuando todo lo que guardás tiene un timestamp y el tiempo es el eje principal, este es el encaje.

Motores de búsqueda: full-text y relevancia

Una caja de búsqueda que perdona los errores de tipeo, ordena las mejores coincidencias primero, y encuentra «running» cuando escribiste «run» — como un bibliotecario que sabe lo que quisiste decir.

Los motores de búsqueda (Elasticsearch, OpenSearch) indexan texto para búsqueda full-text rápida con ranking, coincidencia difusa y filtros — lo que un LIKE '%word%' en SQL hace lento y mal. Normalmente corren junto a tu base de datos principal, mantenidos en sincronía, alimentando la barra de búsqueda y la exploración de logs. No son tu fuente de verdad — una lente rápida sobre ella.

Bases de datos vectoriales: buscar por significado

En vez de coincidir palabras exactas, preguntás «encontrame cosas que se sientan como esta» — y devuelve vecinos por similitud, no por palabra clave.

Las bases de datos vectoriales (pgvector, Pinecone) guardan embeddings — huellas numéricas de significado — y encuentran los más cercanos, así que podés buscar por similitud en vez de por texto exacto. Este es el motor debajo de la búsqueda semántica y RAG, donde una app de IA recupera los fragmentos más relevantes para responder a partir de ellos. El nuevo almacén esencial de la era de la IA.

Almacenamiento de objetos: a dónde van los archivos grandes

Un trastero de autoalmacenamiento — no para fichas, sino para los muebles: cosas voluminosas que guardás por etiqueta y sacás enteras.

El almacenamiento de objetos (S3 y sus parientes) no es una base de datos, pero es donde viven los blobs grandes — imágenes, video, backups, documentos — direccionados por una clave y servidos barato a escala. El patrón es casi universal: guardá el archivo en el almacenamiento de objetos, guardá una fila que apunte a él en tu base de datos. Registros en la DB, payloads en el bucket.

No dobles tu base de datos principal hasta volverla un motor de búsqueda o un servidor de archivos. Poné el trabajo especializado en el almacén construido para él.

§ 05

La elección más profunda de una base de datos no es su forma — es qué promete cuando las cosas salen mal. Una pequeña sopa de letras le pone nombre a ese trueque.

ACID: pesimista, correcta, cuidadosa

Un cajero de banco que vuelve a chequear cada asiento y no avanza hasta que los libros cuadran — más lento, pero nunca equivocado.

ACID (Atomicity, Consistency, Isolation, Durability) es la promesa estricta de las bases de datos relacionales: cada transacción deja los datos correctos y completos, o no sucede en absoluto. Pagás en algo de velocidad, y en un escalado más difícil entre máquinas. Para dinero, pedidos y cualquier cosa donde un número equivocado es inaceptable, este es el trueque que querés.

BASE: optimista, disponible, correcta con el tiempo

Una tienda atareada que deja que todos sigan comprando incluso mientras se actualizan las etiquetas de precio — los números se ponen al día en un momento, y eso está bien.

Muchos sistemas NoSQL toman la postura opuesta: BASE (Basically Available, Soft-state, Eventually consistent). Se mantienen rápidos y disponibles y aceptan que las copias de los datos puedan discrepar brevemente antes de converger. Perfecto cuando la disponibilidad le gana a la precisión instantánea — un contador de likes, un feed, un contador de vistas — y un segundo de desactualización no cuesta nada.

CAP: elegí dos cuando la red se rompe

Un equipo partido por una línea telefónica caída: cada mitad puede seguir trabajando sola (pero divergirán), o soltar las herramientas hasta reconectarse (pero se detienen). No podés tener ambas.

El teorema CAP dice que cuando una partición de red divide las máquinas de tu base de datos, tenés que elegir Consistency (rechazar escrituras, mantenerse correcto) o Availability (seguir sirviendo, arriesgar discrepancia) — no podés tener ambas durante la partición. Toda base de datos distribuida hace esta elección. Saber cuál elige tu almacén te dice cómo se comporta en su peor día.

ACID para el dinero, BASE para los likes. La garantía que necesitás la fija el costo de estar brevemente equivocado.

§ 06

Un puñado de técnicas convierte una base de datos de una sola caja frágil en algo rápido y sobreviviente. Vas a conocerlas todas.

Índices: el índice del libro, para datos

Para encontrar una palabra en un libro de 900 páginas, no leés cada página — saltás al índice del final y vas directo ahí.

Un índice es una estructura lateral que convierte un escaneo de tabla completa en una búsqueda directa — la palanca más grande sobre la velocidad de lectura. La trampa: cada índice cuesta almacenamiento y ralentiza las escrituras (cada inserción tiene que actualizarlo también). Así que indexás las columnas por las que realmente filtrás y ordenás — no cada columna, por las dudas.

Replicación: mantené copias, sobreviví a las fallas

Un documento guardado en tres cajas fuertes en tres edificios — si uno se incendia, los otros todavía lo tienen, y tres personas pueden leerlo a la vez.

La replicación mantiene copias de los datos en varias máquinas: si el líder muere, un seguidor toma el relevo, y las lecturas pueden repartirse entre réplicas. Compra confiabilidad y escalado de lectura. La trampa es el lag de replicación — un seguidor puede ir un momento atrás, así que un valor que acabás de escribir podría no aparecer todavía en una réplica.

Sharding: dividí cuando una caja no alcanza

Un archivador desbordado se vuelve A–M en un archivador y N–Z en otro. Más espacio — pero ahora tenés que saber en qué archivador vive un nombre.

Cuando los datos o la carga de escritura superan a una sola máquina, el sharding divide los datos entre muchas — usuarios A–M acá, N–Z allá. Desbloquea una escala casi ilimitada, pero el shard key es una elección dura y casi permanente: elegí mal y obtenés hotspots, o consultas que tienen que pegarle a cada shard. La replicación copia los mismos datos; el sharding divide datos distintos.

Normalizá, después desnormalizá a propósito

Una lista maestra de direcciones a la que todos se refieren (sin contradicciones) versus grapar una copia de la dirección en cada pedido (más rápido de leer, pero ahora hay copias que mantener honestas).

La normalización mantiene cada hecho en exactamente un lugar — limpio, sin contradicciones, el default relacional. La desnormalización duplica datos deliberadamente para que las lecturas sean más rápidas y necesiten menos joins. Ambas son válidas; la regla es hacerlo conscientemente, y saber siempre cuál copia es la fuente de verdad y cuál es solo un duplicado rápido. (La misma lección que un cache.)

Agregá un índice antes que un servidor, una réplica antes que un shard. El escalado más barato es el que no tenés que operar.

§ 07

No elegís una sola base de datos y forzás todo dentro de ella. Los sistemas reales usan unas cuantas, cada una para el trabajo en el que es mejor.

Polyglot persistence: varios almacenes, a propósito

Una cocina tiene una heladera, un freezer y una despensa — no una sola caja forzada a hacer las tres. Cada una guarda lo que le conviene.

Los sistemas maduros suelen ser polyglot: Postgres como fuente de verdad, Redis para caching y sesiones, un índice de búsqueda para la barra de búsqueda, quizás un almacén vectorial para features de IA y almacenamiento de objetos para archivos. Cada almacén hace aquello en lo que es bueno. La disciplina es mantener claro cuál tiene la verdad, con los otros como copias rápidas mantenidas en sincronía.

Empezá con Postgres; salí de él deliberadamente

Una navaja suiza maneja una cantidad asombrosa antes de que jamás necesites la caja de herramientas completa.

El Postgres moderno es asombrosamente capaz — núcleo relacional, documentos JSON, búsqueda full-text, vectores, hasta una cola de jobs viable. La mayoría de los productos debería empezar solo con Postgres y agregar un almacén especializado únicamente cuando un dolor real y medido lo exija. Cada base de datos extra es otra cosa que correr, respaldar y mantener consistente. El almacén más barato es el que no agregaste.

Antes de elegir una base de datos
  • Qué forma tienen los datos — ¿tablas, documentos, clave-valor, un grafo? - Cómo los voy a consultar — ¿por id, por relaciones, por texto, por similitud, por tiempo? - Qué garantías necesito — ¿ACID estricto, o eventually consistent está bien? - Cuál es el balance lectura/escritura y la escala aproximada? - ¿Podría Postgres ya hacer esto antes de agregar otro almacén? - Cuál almacén tiene la fuente de verdad, y cuáles son solo copias?
Tests de olor de que elegiste mal
  • Estás corriendo LIKE '%...%' para búsqueda en vez de un motor de búsqueda. - Un almacén clave-valor donde constantemente necesitás consultar por los valores. - Cinco bases de datos para un producto que mantienen dos personas. - Elegiste MongoDB para evitar esquemas, y después reconstruiste la validación a mano de todos modos. - Ninguna fuente de verdad clara — dos almacenes que ambos afirman ser autoritativos.
Señales de que elegiste bien
  • La consulta que más corrés es en la que el almacén es más rápido. - La garantía coincide con lo que está en juego — estricta para el dinero, relajada para los likes. - Podés nombrar la fuente de verdad de cada hecho importante. - Agregaste cada almacén para resolver un dolor real y sentido, no uno hipotético. - Podrías explicar el modelo de datos a un ingeniero nuevo en unos pocos minutos.

La mejor decisión de base de datos suele ser «Postgres, por ahora» — más la sabiduría de saber exactamente cuándo terminó ese «por ahora».

Fin del curso exprés · 7 capítulos · almacenes antes que benchmarks

Lo que sigue es la profundidad: Designing Data-Intensive Applications de Martin Kleppmann es el único libro para leer, junto a los docs de Postgres y el manual propio de tu almacén. Pero antes del fondo profundo — imaginá cómo se van a leer, escribir y confiar tus datos. La base de datos es donde tu sistema recuerda; elegí cómo recuerda antes de elegir con qué está construido.