¿Por qué existe NoSQL?
Las bases de datos relacionales (SQL) son excelentes para datos estructurados
con relaciones claras y garantías ACID fuertes. Pero cuando una aplicación crece
a una escala enorme (millones de usuarios, datos muy heterogéneos o de
estructura cambiante), el modelo rígido de tablas y los JOIN pueden volverse
un cuello de botella.
NoSQL ("not only SQL") agrupa bases de datos que renuncian a parte del
modelo relacional (esquema fijo, JOIN, ACID estricto) a cambio de
flexibilidad y escalabilidad horizontal. No es "mejor" que SQL: es una
herramienta distinta para problemas distintos.
Las cuatro familias NoSQL
1. Documentos (MongoDB, CouchDB)
Guardan documentos tipo JSON, con estructura flexible. Cada documento puede tener campos distintos. Ideal cuando los datos son anidados o el esquema evoluciona.
// Un documento en MongoDB
{
_id: "u123",
nombre: "Ada",
direcciones: [ { ciudad: "Madrid" }, { ciudad: "Londres" } ]
}
2. Clave-valor (Redis, DynamoDB)
El modelo más simple: un diccionario gigante clave → valor. Acceso
ultrarrápido por clave. Perfecto para cachés, sesiones y contadores.
SET sesion:ab12 "{usuario: 'Ada'}"
GET sesion:ab12
3. Grafos (Neo4j)
Modelan nodos y relaciones como ciudadanos de primera clase. Brillan cuando lo importante son las conexiones: redes sociales ("amigos de amigos"), recomendaciones, detección de fraude.
4. Columnar / familia de columnas (Cassandra, HBase)
Almacenan los datos por columnas en vez de por filas. Optimizadas para escrituras masivas y consultas analíticas sobre conjuntos enormes (big data).
SQL vs NoSQL: cuándo cada uno
| SQL (relacional) | NoSQL | |
|---|---|---|
| Esquema | fijo, definido por adelantado | flexible o sin esquema |
| Relaciones | JOIN nativo |
desnormalización / anidado |
| Garantías | ACID fuerte | a menudo eventual consistency |
| Escalado | vertical (máquina más potente) | horizontal (más máquinas) |
| Cuándo | datos relacionados, integridad crítica (banca, ERP) | escala masiva, datos flexibles, alta disponibilidad |
El teorema CAP
El teorema CAP (Brewer) describe un límite fundamental de los sistemas distribuidos (datos repartidos en varios nodos). Ante un fallo de red, solo puedes garantizar dos de estas tres propiedades:
- C — Consistencia (Consistency). Toda lectura devuelve el dato más reciente; todos los nodos ven lo mismo.
- A — Disponibilidad (Availability). Toda petición recibe una respuesta (sin errores), aunque no sea el dato más nuevo.
- P — Tolerancia a particiones (Partition tolerance). El sistema sigue funcionando aunque la red entre nodos se corte.
La clave: en un sistema distribuido real, las particiones de red ocurren, así que P es obligatoria. La elección real es entre CP y AP:
- CP (consistencia + tolerancia a particiones): ante un corte, prefiere rechazar peticiones antes que devolver datos viejos. Ej.: bancos.
- AP (disponibilidad + tolerancia a particiones): ante un corte, responde igualmente aunque el dato pueda estar algo desactualizado (eventual consistency). Ej.: feeds de redes sociales, carritos de la compra.
CAP no dice "elige 2 de 3 libremente": en la práctica P viene impuesta, y decides entre consistencia y disponibilidad cuando hay partición.
Escalado: replicación y sharding
Para soportar más carga y datos hay dos estrategias complementarias:
Replicación
Mantener copias de los mismos datos en varios servidores.
- Mejora la disponibilidad (si un nodo cae, otro responde) y la lectura (repartes las consultas entre réplicas).
- Patrón común primario-réplica: las escrituras van al primario y se propagan a las réplicas (que sirven lecturas).
Sharding (particionado horizontal)
Repartir los datos entre varios servidores: cada shard guarda un subconjunto de las filas (p. ej. usuarios A–M en el shard 1, N–Z en el shard 2), según una clave de particionado (shard key).
- Mejora la escritura y la capacidad: ninguna máquina guarda todo.
- Más complejo: las consultas que cruzan shards y mantener el equilibrio entre ellos son difíciles. Elegir bien la shard key es crítico.
Resumen: la replicación copia los mismos datos (alta disponibilidad y lecturas); el sharding reparte datos distintos (escala escritura y volumen). A gran escala se combinan: cada shard, además, replicado.
Ejemplos
Documento JSON (estilo MongoDB)
// En NoSQL de documentos no hay tablas fijas:
const usuario = {
_id: "u42",
nombre: "Grace",
pedidos: [
{ id: 1, total: 120 },
{ id: 8, total: 150 },
],
};
console.log(usuario.pedidos.length); // 2