PostgreSQL vs MongoDB
El campeón de código abierto de las bases de datos relacionales, PostgreSQL, frente a MongoDB, con sus flexibles documentos NoSQL. ¿Cómo elegir la base de datos adecuada según tu modelo de datos?
Base de datos relacional de código abierto que se ejecuta en tu propio servidor, madurando desde 1986
Plataforma backend gestionada y de código abierto, construida sobre PostgreSQL real
Esta decisión no tiene una única respuesta correcta. Si eres un equipo pequeño y la prioridad es la velocidad, Supabase es la elección correcta: auth, storage, realtime y el pooler vienen listos. Con una carga predecible, una restricción de residencia de datos (entre las 17 regiones no está Turquía) o un coste que crece con el número de usuarios, PostgreSQL autoalojado gana. Una advertencia: la documentación oficial indica que el backup/PITR gestionado queda deshabilitado en self-host — con el control heredas el simulacro de restauración. Tener una copia no es el criterio; poder recuperarla sí lo es.
| Categoría | Self-hosted PostgreSQL | Supabase |
|---|---|---|
| Rendimiento | 8/10 | 8/10 |
| Facilidad de aprendizaje | 5/10 | 8/10 |
| Ecosistema | 9/10 | 8/10 |
| Comunidad | 9/10 | 9/10 |
| Mercado laboral | 8/10 | 7/10 |
| A prueba de futuro | 8/10 | 8/10 |
# PostgreSQL autoalojado - configuración de archivado WAL + PITR (postgresql.conf)
wal_level = replica
archive_mode = on
archive_command = 'test ! -f /var/backups/pg_wal_archive/%f && cp %p /var/backups/pg_wal_archive/%f'
max_wal_senders = 3
# Tomar backup base (pg_basebackup)
pg_basebackup -D /var/backups/base -Ft -z -P -U replicator -h localhost
# PITR: volver a un momento concreto (recovery.signal + postgresql.conf)
# 1) Restaurar el backup base en el directorio de restauración
# 2) Añadir estas líneas a postgresql.conf, crear el archivo recovery.signal
restore_command = 'cp /var/backups/pg_wal_archive/%f %p'
recovery_target_time = '2026-09-23 09:00:00+03'
# pg_hba.conf - conexión solo desde el servidor de aplicación
host appdb app_user 10.0.0.5/32 scram-sha-256
-- SQL (psql): instalación de extensiones (libertad total - propio de self-host)
CREATE EXTENSION IF NOT EXISTS vector;
CREATE EXTENSION IF NOT EXISTS postgis;
CREATE EXTENSION IF NOT EXISTS pg_cron;
# Connection pooling (PgBouncer, pgbouncer.ini)
[databases]
appdb = host=127.0.0.1 port=5432 dbname=appdb
[pgbouncer]
pool_mode = transaction
max_client_conn = 500
default_pool_size = 25-- SQL (Supabase SQL Editor): 1) Crear la tabla y activar RLS (la Data API lo exige)
create table public.notes (
id uuid default gen_random_uuid() primary key,
user_id uuid references auth.users not null,
content text not null,
created_at timestamptz default now()
);
alter table public.notes enable row level security;
create policy "kullanicilar kendi notlarini okur"
on public.notes for select
using (auth.uid() = user_id);
create policy "kullanicilar kendi notlarini yazar"
on public.notes for insert
with check (auth.uid() = user_id);
// 2) Consulta con supabase-js (RLS se aplica automáticamente)
import { createClient } from '@supabase/supabase-js'
const supabase = createClient(
process.env.SUPABASE_URL!,
process.env.SUPABASE_ANON_KEY!
)
const { data: notes, error } = await supabase
.from('notes')
.select('id, content, created_at')
.order('created_at', { ascending: false })
// 3) Cadenas de conexión con el cliente Postgres (tabla oficial "Endpoints and IP versions")
// Conexión directa (backend persistente, pg_dump, migration):
// postgresql://postgres:[YOUR-PASSWORD]@db.[PROJECT-REF].supabase.co:5432/postgres
// Dedicated pooler (solo transaction mode, en planes de pago):
// postgresql://postgres:[YOUR-PASSWORD]@db.[PROJECT-REF].supabase.co:6543/postgres
// Configurar la cadena a mano: cópiala desde la pantalla Dashboard > Connect (el host del shared pooler no puede derivarse de la región).Esta decisión no tiene una única respuesta correcta. Si eres un equipo pequeño y la prioridad es la velocidad, Supabase es la elección correcta: auth, storage, realtime y el pooler vienen listos. Con una carga predecible, una restricción de residencia de datos (entre las 17 regiones no está Turquía) o un coste que crece con el número de usuarios, PostgreSQL autoalojado gana. Una advertencia: la documentación oficial indica que el backup/PITR gestionado queda deshabilitado en self-host — con el control heredas el simulacro de restauración. Tener una copia no es el criterio; poder recuperarla sí lo es.
Solicita una consultoría gratuitaComo Supabase usa PostgreSQL estándar, puedes exportar con `pg_dump`/`pg_dumpall` o mediante replicación nativa de Postgres; la documentación oficial explica la migración entre proyectos con un ejemplo de script en Node.js (incluyendo auth/storage). Reconstruir en el lado self-host servicios propios de Supabase como Auth, Storage y Realtime (ejecutando el stack self-host oficial con Docker Compose) es un trabajo aparte — migrar los datos y lograr paridad de servicios son pasos distintos.