Uso de JSON en la base de datos MySQL

1) Introducción

Desde MySQL 5.7 (2015), la base de datos soporta un tipo de dato nativo JSON. Esto permite almacenar y manipular datos estructurados en formato JSON directamente dentro de las tablas, con funciones específicas para:

  • Validar automáticamente que el contenido sea JSON válido.
  • Consultar campos dentro del JSON.
  • Modificar partes del documento sin sobrescribirlo completo.

2) Crear una tabla con columna JSON

CREATE TABLE productos (
    id INT AUTO_INCREMENT PRIMARY KEY,
    nombre VARCHAR(100),
    datos JSON
);

En la columna datos podemos guardar cualquier documento JSON válido.

3) Insertar datos JSON en MySQL

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}');

MySQL valida que los valores sean JSON bien formados.

4) Consultar datos JSON

Consultar la columna completa

SELECT nombre, datos FROM productos;

Extraer un campo específico con -> y ->>

  • -> devuelve valor en formato JSON.
  • ->> devuelve valor como string.
SELECT
    nombre,
    datos->'$.codigo'  AS codigo_json,
    datos->>'$.codigo' AS codigo_texto
FROM productos;

5) Consultas con condiciones sobre JSON

-- Productos cuyo precio > 1000
SELECT nombre, datos->>'$.precio' AS precio
FROM productos
WHERE CAST(datos->>'$.precio' AS DECIMAL(10,2)) > 1000;

6) Actualizar valores dentro del JSON

Usando JSON_SET

-- Cambiar precio de Mouse
UPDATE productos
SET datos = JSON_SET(datos, '$.precio', 900.00)
WHERE nombre = 'Mouse';

Usando JSON_REMOVE

-- Eliminar el campo "tags" del Teclado
UPDATE productos
SET datos = JSON_REMOVE(datos, '$.tags')
WHERE nombre = 'Teclado';

7) Funciones JSON útiles en MySQL

  • JSON_EXTRACT(json_doc, path) — Extrae un valor.
  • JSON_SET(json_doc, path, val) — Inserta o actualiza.
  • JSON_REMOVE(json_doc, path) — Elimina un valor.
  • JSON_ARRAY(val1, val2, ...) — Crea un array JSON.
  • JSON_OBJECT(k1, v1, k2, v2, ...) — Crea un objeto JSON.
  • JSON_MERGE_PATCH(doc1, doc2) — Combina documentos.
  • JSON_LENGTH(json_doc) — Número de elementos.
SELECT JSON_EXTRACT(datos, '$.tags[0]') AS primer_tag
FROM productos
WHERE nombre = 'Teclado';
-- Resultado: "periférico"

8) Índices en columnas JSON

Para mejorar el rendimiento, se pueden crear columnas virtuales basadas en valores JSON y luego indexarlas.

ALTER TABLE productos
ADD COLUMN precio DECIMAL(10,2) GENERATED ALWAYS AS (CAST(datos->>'$.precio' AS DECIMAL(10,2))) STORED,
ADD INDEX (precio);

-- Consulta optimizada
SELECT nombre FROM productos WHERE precio > 1000;

9) Ejemplo avanzado: estructura JSON en pedidos

CREATE TABLE pedidos (
    id INT AUTO_INCREMENT PRIMARY KEY,
    cliente VARCHAR(100),
    detalle JSON
);

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 productos de un pedido
SELECT JSON_EXTRACT(detalle, '$.items') AS items
FROM pedidos
WHERE cliente = 'María';

-- Acceder al primer producto
SELECT detalle->'$.items[0].producto' AS primer_producto
FROM pedidos
WHERE cliente = 'María';

10) Ventajas y desventajas del JSON en MySQL

Ventajas

  • Flexibilidad: mezcla de SQL relacional con documentos JSON.
  • Validación automática de JSON.
  • Funciones poderosas para consultar y modificar.
  • Ideal para datos semiestructurados.

Desventajas

  • Consultas más lentas que en tablas normalizadas si el volumen es grande.
  • Puede dificultar el diseño si se abusa de anidación.
  • No reemplaza completamente a bases NoSQL como MongoDB en grandes volúmenes.

Resumen

  • MySQL soporta un tipo de dato JSON desde la versión 5.7.
  • Permite guardar, consultar y modificar datos estructurados.
  • Tiene funciones como JSON_EXTRACT, JSON_SET, JSON_REMOVE.
  • Se pueden crear columnas virtuales e índices para optimizar búsquedas.
  • Es útil cuando se necesita un equilibrio entre estructura SQL y flexibilidad JSON.