PostgreSQL es una de las bases de datos relacionales que mejor soporte nativo tiene para JSON.
JSON
.Diferencia clave:
JSON — almacena texto JSON tal cual se inserta (se guarda con formato).
JSONB — almacena en formato binario optimizado (más rápido para consultas e índices, ignora espacios y orden de claves). En la práctica, se recomienda usar JSONB.
CREATE TABLE productos (
id SERIAL PRIMARY KEY,
nombre VARCHAR(100),
datos JSONB
);
INSERT INTO productos (nombre, datos) VALUES
('Teclado', '{"codigo":101, "precio":1200.50, "disponible":true, "tags":["periférico","oferta"]}'),
('Mouse', '{"codigo":102, "precio":850.75, "disponible":false}');
-- PostgreSQL valida automáticamente que los datos sean JSON bien formado.
Extraer un campo con ->
y ->>
->
devuelve JSON.->>
devuelve texto.SELECT
nombre,
datos->'codigo' AS codigo_json,
datos->>'codigo' AS codigo_texto
FROM productos;
-- Productos con precio > 1000
SELECT nombre, datos->>'precio' AS precio
FROM productos
WHERE (datos->>'precio')::DECIMAL > 1000;
Usando jsonb_set
-- Cambiar precio del Mouse
UPDATE productos
SET datos = jsonb_set(datos, '{precio}', '900.00'::jsonb)
WHERE nombre = 'Mouse';
Eliminar campos con -
-- Eliminar el campo "tags" del Teclado
UPDATE productos
SET datos = datos - 'tags'
WHERE nombre = 'Teclado';
Agregar un nuevo campo
UPDATE productos
SET datos = jsonb_set(datos, '{stock}', '50'::jsonb)
WHERE nombre = 'Teclado';
-- Extraer el primer tag del Teclado
SELECT datos->'tags'->>0 AS primer_tag
FROM productos
WHERE nombre = 'Teclado';
jsonb_set(doc, path, new_value)
— modifica o agrega un campo.jsonb_insert(doc, path, new_value)
— inserta en una posición específica.jsonb_array_elements(array)
— expande un array en filas.jsonb_each(doc)
— devuelve pares clave-valor.jsonb_object_keys(doc)
— lista las claves de un objeto.jsonb_agg(valores)
— agrupa resultados como un array JSON.row_to_json
/ json_build_object
— convierte filas SQL a JSON.-- Expandir un array
SELECT jsonb_array_elements_text(datos->'tags') AS tag
FROM productos
WHERE nombre = 'Teclado';
-- Resultado: periférico, oferta
PostgreSQL permite indexar campos JSONB usando GIN (Generalized Inverted Index).
CREATE INDEX idx_productos_datos ON productos USING GIN (datos);
-- Consulta optimizada
SELECT * FROM productos
WHERE datos @> '{"disponible": true}';
-- El operador @> significa "contiene".
CREATE TABLE pedidos (
id SERIAL PRIMARY KEY,
cliente VARCHAR(100),
detalle JSONB
);
INSERT INTO pedidos (cliente, detalle) VALUES
('María', '{
"items": [
{"producto": "Notebook", "cantidad": 1, "precio": 2500.00},
{"producto": "Mouse", "cantidad": 2, "precio": 850.75}
],
"total": 4201.50
}');
-- Consultar todos los items
SELECT jsonb_array_elements(detalle->'items') AS item
FROM pedidos
WHERE cliente = 'María';
-- Solo la cantidad del primer producto
SELECT detalle->'items'->0->>'cantidad' AS cantidad
FROM pedidos
WHERE cliente = 'María';
SELECT json_build_object(
'id', id,
'cliente', cliente,
'detalle', detalle
) AS pedido_json
FROM pedidos;
Ventajas
Desventajas
jsonb_set
, jsonb_array_elements
, json_build_object
).