PostgreSQL en Supabase: Fundamentos

Supabase usa PostgreSQL como su base de datos. No es una versión simplificada ni un wrapper -- es PostgreSQL completo, con todas sus funcionalidades: tipos de datos, funciones, triggers, índices, vistas, extensiones.

Esto significa que todo lo que aprendas de PostgreSQL aplica directamente en Supabase. No estás aprendiendo una tecnología propietaria que solo sirve en una plataforma.

Qué es PostgreSQL

PostgreSQL (o simplemente Postgres) es un sistema de base de datos relacional open-source. "Relacional" significa que los datos se organizan en tablas con filas y columnas, y puedes definir relaciones entre esas tablas.

Es la base de datos más avanzada del mundo open-source. Lleva más de 35 años de desarrollo activo y la usan empresas como Apple, Instagram, Spotify y Twitch.

En Supabase, cada proyecto tiene su propia instancia de PostgreSQL. Tú tienes acceso completo como superusuario -- puedes crear tablas, funciones, triggers, y cualquier cosa que PostgreSQL soporte.

SQL: el lenguaje de las bases de datos

SQL (Structured Query Language -- lenguaje de consulta estructurado) es el lenguaje que usas para comunicarte con PostgreSQL. Con SQL puedes crear tablas, insertar datos, consultarlos, actualizarlos y eliminarlos.

Las cuatro operaciones fundamentales se conocen como CRUD:

  • Create -- Crear (INSERT)
  • Read -- Leer (SELECT)
  • Update -- Actualizar (UPDATE)
  • Delete -- Eliminar (DELETE)

SELECT: leer datos

sql
-- Obtener todos los productos
SELECT * FROM productos;
 
-- Obtener solo nombre y precio
SELECT nombre, precio FROM productos;
 
-- Filtrar por condicion
SELECT * FROM productos WHERE precio > 100;
 
-- Ordenar resultados
SELECT * FROM productos ORDER BY precio DESC;
 
-- Limitar resultados
SELECT * FROM productos LIMIT 10;
 
-- Combinar filtros
SELECT nombre, precio
FROM productos
WHERE categoria = 'electronica'
  AND precio > 50
ORDER BY precio ASC
LIMIT 20;

El asterisco (*) significa "todas las columnas". En producción es mejor especificar las columnas que necesitas para no traer datos innecesarios.

INSERT: crear datos

sql
-- Insertar un producto
INSERT INTO productos (nombre, precio, categoria)
VALUES ('Monitor 27 pulgadas', 4500, 'electronica');
 
-- Insertar multiples registros
INSERT INTO productos (nombre, precio, categoria)
VALUES
  ('Teclado mecanico', 1200, 'electronica'),
  ('Mouse inalambrico', 650, 'electronica'),
  ('Webcam HD', 890, 'electronica');
 
-- Insertar y obtener el registro creado
INSERT INTO productos (nombre, precio, categoria)
VALUES ('Audifonos Bluetooth', 1800, 'electronica')
RETURNING *;

RETURNING * es una funcionalidad de PostgreSQL que te devuelve el registro recién creado, incluyendo columnas auto-generadas como id y created_at.

UPDATE: actualizar datos

sql
-- Actualizar un producto por su ID
UPDATE productos
SET precio = 4200
WHERE id = 'a1b2c3d4-e5f6-7890-abcd-ef1234567890';
 
-- Actualizar multiples columnas
UPDATE productos
SET precio = 4200, nombre = 'Monitor 27" 4K'
WHERE id = 'a1b2c3d4-e5f6-7890-abcd-ef1234567890';
 
-- Actualizar multiples registros
UPDATE productos
SET disponible = false
WHERE stock = 0;
 
-- Actualizar y obtener el resultado
UPDATE productos
SET precio = precio * 0.9
WHERE categoria = 'electronica'
RETURNING nombre, precio;
Siempre usa WHERE en UPDATE

Si ejecutas UPDATE productos SET precio = 0 sin WHERE, vas a actualizar TODOS los registros de la tabla. Siempre filtra qué registros quieres modificar.

DELETE: eliminar datos

sql
-- Eliminar un producto
DELETE FROM productos
WHERE id = 'a1b2c3d4-e5f6-7890-abcd-ef1234567890';
 
-- Eliminar multiples registros
DELETE FROM productos
WHERE disponible = false AND stock = 0;
 
-- Eliminar y ver que se elimino
DELETE FROM productos
WHERE categoria = 'descontinuado'
RETURNING *;
Siempre usa WHERE en DELETE

Igual que con UPDATE: DELETE FROM productos sin WHERE elimina TODOS los registros. No hay "deshacer" en SQL.

Cómo ejecutar SQL en Supabase

Tienes dos formas principales de interactuar con tu base de datos: el SQL Editor en el dashboard y el SDK desde tu código.

SQL Editor

El SQL Editor es una herramienta integrada en el dashboard de Supabase donde puedes escribir y ejecutar queries SQL directamente contra tu base de datos.

Para acceder:

  1. Abre tu proyecto en supabase.com/dashboard
  2. En el menú lateral, haz clic en SQL Editor
  3. Escribe tu query y presiona Run (o Ctrl/Cmd + Enter)
sql
-- Puedes ejecutar cualquier SQL valido en el editor
CREATE TABLE IF NOT EXISTS notas (
  id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
  titulo text NOT NULL,
  contenido text,
  created_at timestamptz DEFAULT now()
);
 
INSERT INTO notas (titulo, contenido)
VALUES ('Mi primera nota', 'Esto se ejecuto desde el SQL Editor');
 
SELECT * FROM notas;

El SQL Editor es ideal para:

  • Explorar datos manualmente
  • Crear y modificar tablas
  • Probar queries antes de llevarlas al código
  • Ejecutar migraciones
  • Debuggear problemas con los datos

SDK de Supabase

El SDK (Software Development Kit) es la librería @supabase/supabase-js que instalas en tu proyecto. Te permite interactuar con la base de datos desde tu código TypeScript o JavaScript.

typescript
import { createClient } from '@supabase/supabase-js'
 
const supabase = createClient(
  process.env.NEXT_PUBLIC_SUPABASE_URL!,
  process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
)
 
// SELECT * FROM productos WHERE categoria = 'electronica' ORDER BY precio ASC LIMIT 10
const { data, error } = await supabase
  .from('productos')
  .select('*')
  .eq('categoria', 'electronica')
  .order('precio', { ascending: true })
  .limit(10)
Variables de entorno

NEXT_PUBLIC_SUPABASE_URL y NEXT_PUBLIC_SUPABASE_ANON_KEY son las credenciales de tu proyecto. Las encuentras en el dashboard de Supabase bajo Settings > API. Nunca las expongas directamente en tu código -- siempre usa variables de entorno.

SQL vs SDK: cuándo usar cada uno

Ambas formas llegan al mismo lugar (tu base de datos PostgreSQL), pero cada una tiene su momento.

Usa el SDK cuando:

  • Construyes tu aplicación (frontend o backend)
  • Necesitas que las queries respeten RLS (Row Level Security)
  • Quieres type safety con TypeScript
  • Estás haciendo CRUD estándar
typescript
// El SDK es perfecto para operaciones CRUD comunes
const { data: productos } = await supabase
  .from('productos')
  .select('id, nombre, precio')
  .eq('disponible', true)
  .order('created_at', { ascending: false })

Usa SQL directo cuando:

  • Creas o modificas la estructura de la base de datos (DDL)
  • Necesitas queries complejas con JOINs múltiples
  • Creas funciones, triggers o vistas
  • Haces migraciones
  • Ejecutas operaciones administrativas
sql
-- El SQL Editor es mejor para operaciones estructurales
CREATE INDEX idx_productos_categoria ON productos(categoria);
 
CREATE VIEW productos_activos AS
SELECT id, nombre, precio
FROM productos
WHERE disponible = true AND stock > 0;

Tabla comparativa

OperaciónSQL EditorSDK
SELECT simpleSí (recomendado)
INSERT/UPDATE/DELETESí (recomendado)
Crear tablasSí (recomendado)No
Crear índicesSí (recomendado)No
Crear funcionesSí (recomendado)No
Queries con RLSNo aplica RLS (admin)Sí (aplica RLS)
Desde tu appNoSí (recomendado)
Regla práctica

Si es una operación sobre la estructura de la base de datos (CREATE, ALTER, DROP), usa SQL. Si es una operación sobre los datos (SELECT, INSERT, UPDATE, DELETE) desde tu aplicación, usa el SDK.

Conceptos clave de PostgreSQL

Antes de avanzar, asegúrate de tener claros estos conceptos que vas a encontrar constantemente:

Schemas

Un schema (esquema) es como un namespace para tus tablas. Supabase usa el schema public por defecto para tus tablas, y tiene otros schemas internos como auth (para autenticación) y storage (para archivos).

sql
-- Estas dos queries son equivalentes
SELECT * FROM productos;
SELECT * FROM public.productos;

Null

NULL en SQL significa "sin valor" -- no es lo mismo que una cadena vacía ('') ni que cero (0). Es la ausencia total de valor.

sql
-- Buscar registros donde descripcion es null
SELECT * FROM productos WHERE descripcion IS NULL;
 
-- Buscar registros donde descripcion NO es null
SELECT * FROM productos WHERE descripcion IS NOT NULL;

Transacciones

Una transacción agrupa varias operaciones SQL en una sola unidad. Si alguna falla, todas se revierten. Esto garantiza que tus datos queden en un estado consistente.

sql
BEGIN;
  UPDATE cuentas SET saldo = saldo - 500 WHERE id = 'cuenta_origen';
  UPDATE cuentas SET saldo = saldo + 500 WHERE id = 'cuenta_destino';
COMMIT;

Si el segundo UPDATE falla, el primero también se revierte. Nadie pierde dinero.

Siguiente paso

Con estos fundamentos de SQL y PostgreSQL, estás listo para crear tus propias tablas. En la siguiente sección vamos a ver los tipos de datos disponibles, cómo definir columnas, y cómo crear una tabla real paso a paso.