Bases de datos relacionales frente a NoSQL: cómo elegir la base adecuada para tu sistema
La elección entre una base de datos relacional y una NoSQL es una de las decisiones arquitectónicas más trascendentales que tomarás. Si aciertas, tu sistema se ampliará sin problemas. Si te equivocas, te pasarás años luchando contra tu base de datos. Esto es lo que realmente necesitas saber.
Todas las bases de datos almacenan datos. Ahí es donde terminan las similitudes. Las bases de datos relacionales y las bases de datos NoSQL representan filosofías fundamentalmente diferentes sobre cómo deben estructurarse, almacenarse y consultarse los datos, y esas diferencias se propagan por todas las capas de los sistemas construidos sobre ellas.
No se trata de una cuestión de lo antiguo frente a lo nuevo, ni de lo sencillo frente a lo sofisticado. Ambas categorías contienen sistemas maduros y probados en la práctica que se utilizan a una escala extraordinaria. La cuestión es la idoneidad para el propósito: qué modelo se adapta mejor a la estructura de tus datos, a los patrones de acceso de tu aplicación y a las garantías de consistencia que requieren tus usuarios.
Qué es realmente una base de datos relacional
Una base de datos relacional organiza los datos en tablas: filas y columnas con relaciones explícitamente definidas entre ellas. El término «relacional» del nombre no se refiere al hecho de que las tablas estén relacionadas entre sí (aunque lo están), sino al concepto matemático de una relación: un conjunto de tuplas que comparten los mismos atributos. Este fundamento teórico, desarrollado por Edgar Codd en IBM en 1970, ha demostrado ser extraordinariamente duradero.
Las características fundamentales de una base de datos relacional son:
Un esquema fijo. Antes de insertar datos, se define la estructura: qué tablas existen, qué columnas tiene cada tabla, qué tipo de datos acepta cada columna y qué restricciones se aplican (NOT NULL, UNIQUE, CHECK, etc.). El esquema es el contrato entre tu aplicación y tu base de datos.
Normalización. Los datos se organizan para eliminar la redundancia. El nombre de un cliente aparece una sola vez, en la tabla de clientes. Cada pedido hace referencia a ese cliente mediante su ID. Si el nombre cambia, solo cambia en un lugar. No se trata solo de orden, sino de una garantía de coherencia.
Transacciones ACID. Atomicidad, consistencia, aislamiento y durabilidad. Una transacción se completa en su totalidad o no se completa en absoluto. Si transfieres dinero de una cuenta a otra, el cargo y el abono se producen a la vez o ninguno de los dos se produce. La base de datos garantiza esto a nivel del motor.
SQL. El Lenguaje de Consulta Estructurado (SQL) es la interfaz universal para las bases de datos relacionales. Es declarativo —describes lo que quieres, no cómo conseguirlo— y es extraordinariamente expresivo. Uniones, agregaciones, funciones de ventana, subconsultas, CTE: toda la amplitud de SQL te ofrece herramientas para plantear preguntas complejas sobre tus datos sin necesidad de escribir código de aplicación para realizar el trabajo.
Las principales bases de datos relacionales —PostgreSQL, MySQL, SQL Server, Oracle— comparten estas propiedades, aunque difieren en sus conjuntos de características específicas, sus características de rendimiento y sus modelos de licencia. PostgreSQL, en particular, se ha convertido en la opción predeterminada para nuevos proyectos, ya que combina un estricto cumplimiento de los estándares con un conjunto de características excepcional.
¿Qué es realmente una base de datos NoSQL?
«NoSQL» es un término genérico que abarca varias categorías distintas de bases de datos, unidas principalmente por lo que no son: no son relacionales y no utilizan SQL como interfaz principal (aunque algunas admiten lenguajes de consulta similares a SQL). El término se entiende mejor como «no solo SQL», lo que supone reconocer que el modelo relacional no es el único enfoque válido.
Las principales categorías de NoSQL son:
Las bases de datos de documentos almacenan los datos como documentos —normalmente JSON o BSON—, en los que cada documento puede tener una estructura diferente. MongoDB es la más utilizada; otras son CouchDB y Firestore. No hay tablas ni esquema fijo; una «colección» de documentos puede contener registros con campos totalmente diferentes.
Los almacenes clave-valor son el modelo más sencillo: cada registro es un valor al que se puede acceder mediante una clave única. Redis es el ejemplo más destacado, utilizado ampliamente para el almacenamiento en caché, el almacenamiento de sesiones y las clasificaciones en tiempo real. DynamoDB también funciona principalmente como un almacén clave-valor, con capacidades de gestión de documentos integradas.
Los almacenes de familias de columnas organizan los datos por columnas en lugar de por filas, lo que permite lecturas extremadamente eficientes de columnas específicas entre millones de filas. Apache Cassandra y HBase son los principales ejemplos. Este modelo está diseñado para cargas de trabajo con gran volumen de escrituras y en las que los patrones de consulta se conocen de antemano.
Las bases de datos de grafos modelan los datos como nodos y aristas: entidades y las relaciones entre ellas. Neo4j es el ejemplo más destacado. Cuando las relaciones entre entidades son el tema principal de tus consultas —redes sociales, motores de recomendación, detección de fraudes—, las bases de datos de grafos pueden expresar esas consultas de forma natural, algo que requeriría un SQL profundamente recursivo.
Las bases de datos de series temporales están optimizadas para datos indexados por tiempo: InfluxDB, TimescaleDB, Prometheus. Lecturas de sensores, cotizaciones financieras, métricas de aplicaciones: datos en los que la marca de tiempo es siempre la clave principal y las consultas por intervalos de tiempo constituyen el patrón de acceso predominante.
La diferencia estructural que lo determina todo
La diferencia más profunda entre las bases de datos relacionales y las NoSQL no radica en la sintaxis ni en la escala, sino en la relación entre la estructura de los datos y la flexibilidad de las consultas.
Las bases de datos relacionales te ofrecen la máxima flexibilidad en las consultas a cambio de una disciplina inicial en el esquema. Dado que los datos están normalizados y tipificados, puedes plantearles casi cualquier pregunta en el momento de la consulta. Puedes unir tablas de formas que nunca habías previsto al diseñar el esquema. Puedes realizar agregaciones a través de dimensiones que hayas añadido meses después del diseño inicial. El esquema limita los datos, pero el lenguaje de consulta te da libertad.
Las bases de datos NoSQL hacen la concesión opuesta. Ofrecen flexibilidad a la hora de estructurar y escribir datos, a cambio de patrones de consulta más limitados. Una base de datos de documentos permite almacenar datos de cualquier formato sin necesidad de migración. Sin embargo, realizar consultas eficientes entre documentos requiere conocer de antemano los patrones de acceso y diseñar la estructura de datos en función de ellos.
Esta es la tensión fundamental: flexibilidad del esquema frente a flexibilidad de consulta. Puedes tener ambas, pero solo hasta cierto punto. El modelo de base de datos que elijas refleja qué compensación resulta más aceptable para tu caso de uso.
El teorema CAP y por qué es importante
Los sistemas distribuidos no pueden garantizar simultáneamente la consistencia, la disponibilidad y la tolerancia a particiones: como máximo, pueden alcanzar dos de las tres. Este es el teorema CAP, y constituye la base teórica para comprender por qué las bases de datos relacionales y NoSQL se comportan de forma diferente en condiciones de fallo.
Las bases de datos relacionales suelen dar prioridad a la consistencia y a la tolerancia a particiones. Cada lectura refleja la escritura más reciente. Si se produce una partición de red y la base de datos no puede garantizar la consistencia, se negará a servir datos obsoletos: dejará de estar disponible en lugar de mostrar datos incorrectos.
Muchas bases de datos NoSQL —especialmente aquellas diseñadas para la distribución horizontal, como Cassandra y DynamoDB— dan prioridad a la disponibilidad y a la tolerancia a particiones. Suministrarán datos incluso durante una partición de red, aceptando que algunas lecturas puedan devolver valores obsoletos. Esto es la «consistencia eventual»: todos los nodos acabarán convergiendo en el mismo valor, pero hay un intervalo de tiempo durante el cual pueden no coincidir.
La implicación práctica: si tu aplicación no puede tolerar en ningún caso la lectura de datos obsoletos —un saldo bancario, un recuento de inventario, un historial médico—, necesitas consistencia fuerte. Si tu aplicación puede tolerar una breve inconsistencia a cambio de estar siempre disponible —un feed de redes sociales, un catálogo de productos, un perfil de usuario—, la consistencia eventual es aceptable y te ofrece libertad arquitectónica.
Ejemplos del mundo real: cuando la elección correcta marcó la diferencia
GitHub: PostgreSQL en el centro de una plataforma global
GitHub gestiona una de las plataformas de colaboración de software más grandes del mundo con PostgreSQL: millones de repositorios, miles de millones de eventos y complejas consultas relacionales que abarcan usuarios, organizaciones, repositorios, solicitudes de incorporación de cambios, incidencias y comentarios. El modelo relacional se adapta al ámbito: las relaciones entre estas entidades constituyen el producto. Una solicitud de incorporación de cambios pertenece a un repositorio, es creada por un usuario, revisada por otros usuarios, cierra incidencias y activa flujos de trabajo de integración continua (CI).
Durante años, GitHub operó una única instancia principal de PostgreSQL con réplicas de lectura. A medida que la escala crecía, introdujeron Vitess (una capa de fragmentación de MySQL para algunas cargas de trabajo) y ProxySQL para la gestión de conexiones, pero el núcleo relacional se mantuvo. La lección no es que PostgreSQL escale infinitamente sin esfuerzo. Es que el modelo relacional era el más adecuado para un ámbito definido por relaciones, y el esfuerzo invertido en escalarlo mereció la pena precisamente porque migrar a un modelo de datos diferente habría resultado más costoso.
Twitter: la dolorosa migración de MySQL a una arquitectura mixta
Twitter comenzó con MySQL y se enfrentó a una crisis de escalabilidad bien documentada, ya que el crecimiento del número de usuarios superó la capacidad de una única base de datos relacional. El problema principal era el grafo social —las relaciones de seguidores y seguidos entre cientos de millones de usuarios— y el problema de la dispersión de la cronología: cuando un usuario con 10 millones de seguidores tuitea, ese tuit debe aparecer en 10 millones de cronologías de forma casi instantánea.
El modelo relacional, tal y como lo había implementado Twitter, no podía gestionar esta difusión de escrituras a la velocidad requerida. Twitter migró el grafo social a un almacén personalizado en memoria y, finalmente, adoptó Manhattan (su almacén interno distribuido de clave-valor) para las cronologías y Cassandra para otras cargas de trabajo con un alto volumen de escrituras.
La lección que se extrae de esto tiene sus matices. Los datos fundamentales de Twitter —tuits, usuarios, relaciones— son, en esencia, relacionales. El problema no era el modelo de datos, sino el volumen de escritura y la difusión a una escala que exigía la distribución. La migración resultó costosa, técnicamente compleja y requirió años de inversión en ingeniería. A la escala de Twitter, fue la decisión acertada. A la escala de casi cualquier otra aplicación, habría sido prematuro.
MongoDB: una historia con moraleja sobre la flexibilidad del esquema
A principios de la década de 2010, a medida que MongoDB ganaba popularidad rápidamente, muchos equipos lo adoptaron principalmente por su flexibilidad de esquema —la capacidad de empezar a almacenar datos sin definir primero un esquema—. Para la creación de prototipos y el desarrollo en fases iniciales, esto aceleró realmente la iteración.
Los problemas surgieron a medida que los sistemas maduraban. Sin la aplicación de un esquema, la inconsistencia de los datos se fue acumulando gradualmente. A veces faltaban campos que deberían haber sido obligatorios. Valores que deberían haber sido enteros resultaban ser, en ocasiones, cadenas de caracteres. Las consultas que asumían una estructura coherente devolvían resultados inesperados. Los equipos se vieron obligados a escribir extensas validaciones a nivel de aplicación que la base de datos habría aplicado de forma automática.
Esto no supone un fracaso de MongoDB como base de datos —es una herramienta adecuada para muchos casos de uso—. Se trata más bien de un error al dar por sentado que la flexibilidad del esquema es incondicionalmente positiva. La flexibilidad aplazó el coste de reflexionar sobre la estructura de los datos; no lo eliminó. Los equipos que utilizaban MongoDB sin disciplina se vieron obligados a implementar una versión deficiente de un esquema relacional en el código de la aplicación, sin las garantías que habría proporcionado una base de datos relacional.
Amazon DynamoDB: un caso de éxito para el caso de uso adecuado
El carrito de la compra de Amazon es uno de los ejemplos canónicos de un uso acertado de NoSQL. Los requisitos eran claros: el carrito de la compra debía estar siempre disponible (un cliente debía poder añadir artículos en todo momento, incluso durante un fallo regional), debía gestionar un volumen masivo de escrituras (cientos de millones de usuarios añadiendo y eliminando artículos) y el patrón de acceso era sencillo y conocido de antemano (acceso siempre mediante el ID de cliente).
El equipo de ingeniería de Amazon, en el artículo de 2007 que inspiró DynamoDB, describió cómo se optó deliberadamente por la consistencia eventual para el carrito: si dos dispositivos añadían artículos simultáneamente durante una partición de red, ambas adiciones se conservarían cuando se restableciera la conexión, aunque ello supusiera mostrar brevemente un estado ligeramente inconsistente. Un carrito de la compra en el que siempre se pueda escribir —incluso a costa de una breve inconsistencia— es más valioso que un carrito que a veces no está disponible.
El diseño de DynamoDB en torno a este caso de uso —acceso sencillo de clave-valor, patrones de consulta conocidos, disponibilidad por encima de la consistencia— es lo que lo hace excelente. Las aplicaciones que intentan utilizar DynamoDB como una base de datos relacional de uso general, ejecutando consultas complejas en múltiples entidades, suelen tener dificultades.
Airbnb: Elasticsearch para la búsqueda, PostgreSQL para la información de referencia
La búsqueda de Airbnb —que filtra los anuncios por ubicación, fechas, precio, servicios y disponibilidad— es una consulta que ninguna base de datos relacional puede gestionar de forma eficiente a gran escala. La combinación de búsqueda geográfica, coincidencia de texto completo y filtrado complejo por múltiples atributos en millones de anuncios es precisamente el caso de uso para el que se diseñó Elasticsearch.
Airbnb utiliza Elasticsearch como capa de búsqueda, al tiempo que mantiene PostgreSQL como sistema de registro. Cuando se actualiza un anuncio, el cambio se escribe en PostgreSQL (la fuente de verdad, con garantías ACID completas) y, a continuación, se propaga de forma asíncrona a Elasticsearch (el índice de búsqueda, optimizado para los patrones de consulta específicos de la experiencia de búsqueda).
Se trata de un patrón arquitectónico consolidado: utilizar la base de datos adecuada para cada necesidad, mantener una fuente de verdad clara y aceptar la complejidad operativa que supone mantener sincronizados varios almacenes de datos. Funciona porque los límites están claros y se comprenden las compensaciones.

Cuándo elegir una base de datos relacional
Una base de datos relacional es la opción predeterminada adecuada para la mayoría de las aplicaciones. Los casos en los que es claramente la elección correcta:
Tus datos tienen relaciones significativas. Si las entidades de tu sistema se relacionan entre sí de formas relevantes —usuarios y sus publicaciones, pedidos y sus partidas, proyectos y sus tareas—, el modelo relacional representa esas relaciones directamente y te permite realizar consultas entre ellas de manera eficiente.
Necesitas una consistencia sólida. Transacciones financieras, gestión de inventario, sistemas de reservas, historiales médicos… cualquier ámbito en el que una lectura incorrecta tenga consecuencias reales requiere garantías ACID. Una base de datos relacional proporciona esto a nivel del motor.
No conoces por completo tus patrones de consulta. Si tu aplicación tendrá que responder a preguntas sobre tus datos que no puedes prever por completo en la fase de diseño, la flexibilidad de SQL resulta muy valiosa. La capacidad de escribir una consulta ad hoc sobre un esquema bien normalizado es un activo operativo significativo.
Tu equipo conoce SQL. Esto puede parecer trivial, pero no lo es. SQL es una de las competencias técnicas más extendidas en ingeniería de software. Todos los desarrolladores que contrates lo conocerán en mayor o menor medida. Los conocimientos operativos —cómo añadir un índice, cómo interpretar un plan de consulta, cómo gestionar copias de seguridad— están ampliamente disponibles. El ecosistema de herramientas está maduro.
No estás seguro de lo que necesitas. En caso de duda, empieza con PostgreSQL. Es más fácil introducir un almacén especializado más adelante, una vez que comprendas tus patrones de acceso reales, que migrar desde un almacén de documentos de vuelta a un modelo relacional cuando tus datos resulten estar más estructurados de lo que pensabas.
Cuándo elegir NoSQL
NoSQL es la elección adecuada cuando el modelo relacional no puede satisfacer un requisito específico sin un esfuerzo desproporcionado:
El volumen de escrituras supera lo que puede gestionar un único nodo. Si tu aplicación necesita soportar cientos de miles de escrituras por segundo en un sistema distribuido geográficamente, se hace necesario el escalado horizontal a través de muchos nodos. Los almacenes de familias de columnas como Cassandra están diseñados para esto; las bases de datos relacionales pueden distribuirse, pero no es su modo natural de funcionamiento.
Tus datos carecen realmente de esquema o son muy variables. Un catálogo de productos en el que los distintos tipos de productos tienen atributos totalmente diferentes, un CMS en el que los tipos de contenido evolucionan rápidamente, un sistema de registro en el que los esquemas de eventos los definen sistemas externos: estos casos se benefician del almacenamiento de documentos, en el que la base de datos no impone ninguna estructura.
Tu patrón de acceso principal es la búsqueda de clave-valor a escala extrema. Almacenes de sesiones, cachés, clasificaciones en tiempo real, indicadores de características: las cargas de trabajo en las que siempre se accede a los datos mediante una única clave y nunca es necesario realizar uniones ni agregaciones se benefician de la simplicidad y el rendimiento de un almacén de clave-valor.
Estás modelando un grafo. Si tus consultas principales consisten en recorrer relaciones —encontrar a todos los amigos de tus amigos, identificar la ruta más corta entre dos nodos, detectar dependencias circulares—, una base de datos de grafos expresará esas consultas de forma más natural y las ejecutará de manera más eficiente que el SQL recursivo.
Necesitas optimización de series temporales. Millones de lecturas de sensores, datos financieros o métricas de aplicaciones por segundo, con consultas que se realizan principalmente sobre intervalos de tiempo, se gestionan mejor con una base de datos de series temporales diseñada específicamente para ello que con un almacén relacional con una columna de marca de tiempo.
La realidad de las bases de datos múltiples
Lo más importante que hay que entender sobre la cuestión «relacional frente a NoSQL» es que, en la mayoría de los sistemas maduros, no se trata de una elección excluyente. Los sistemas a gran escala utilizan habitualmente varias bases de datos, cada una de ellas elegida para la carga de trabajo específica a la que da servicio.
PostgreSQL para el sistema de registro. Redis para el almacenamiento en caché de sesiones y la limitación de tasa. Elasticsearch para la búsqueda de texto completo. InfluxDB para las métricas de aplicaciones. Cada base de datos de esta pila hace lo que mejor sabe hacer, y la capa de aplicación gestiona la coherencia entre ellas.
El coste operativo de esta complejidad es real. Cada base de datos adicional supone otro sistema que hay que supervisar, del que hay que hacer copias de seguridad, escalar y comprender. La disciplina de ingeniería necesaria para mantener la coherencia entre múltiples almacenes —gestionando escenarios de fallo en los que una escritura en PostgreSQL se realiza con éxito, pero la actualización posterior en Elasticsearch falla— no es trivial.
El punto de partida para casi todas las aplicaciones debería ser una única base de datos relacional. Añade bases de datos especializadas cuando no se pueda cumplir un requisito específico y bien definido sin ellas. La diversificación prematura de las bases de datos es una forma de optimización prematura: añade complejidad antes de que se comprenda si dicha complejidad es necesaria.

Tomar la decisión
Las preguntas que realmente importan a la hora de elegir una base de datos:
¿Cuáles son tus requisitos de consistencia? Si la respuesta a «¿qué ocurre si un usuario lee datos obsoletos?» es «eso es un problema grave», necesitas ACID. Si la respuesta es «eso es un poco molesto, pero aceptable», tienes varias opciones.
¿Cuáles son tus patrones de consulta? Si sabes exactamente cómo se accederá a tus datos y ese patrón de acceso es sencillo y de gran volumen, puedes optimizarlo en consecuencia. Si tus patrones de acceso son complejos o no se conocen del todo, la flexibilidad de SQL resulta muy valiosa.
¿Cuál es tu volumen de escritura? Para la gran mayoría de las aplicaciones, una instancia de PostgreSQL bien ajustada en un hardware razonable gestiona miles de escrituras por segundo sin dificultad. Los casos en los que esto resulta realmente insuficiente son más raros de lo que sugería el bombo publicitario de NoSQL de la década de 2010.
¿Cuál es la estructura de tus datos? Los datos muy uniformes y estrechamente relacionados se adaptan bien al modelo relacional. Los datos muy variables y poco relacionados pueden encajar mejor en un modelo de documentos.
¿Qué conocimientos tiene tu equipo? La familiaridad operativa es importante. Un equipo que conozca a fondo PostgreSQL construirá un sistema más fiable con PostgreSQL que con una base de datos NoSQL que esté aprendiendo a utilizar, incluso si esta última fuera, en teoría, más adecuada.
La base de datos relacional ha sobrevivido a cincuenta años de cambios tecnológicos no porque sea siempre la mejor herramienta, sino porque es una opción por defecto excepcionalmente buena: flexible, fiable, bien comprendida y respaldada por décadas de conocimiento operativo. Aléjate de ella deliberadamente, con una comprensión clara de lo que ganas y de lo que sacrificas.