Volver a MySQL Intermedio
JSON y Document Store en MySQL
Modelado de Datos con JSON
CREATE TABLE productos (
id INT PRIMARY KEY AUTO_INCREMENT,
sku VARCHAR(50) NOT NULL UNIQUE,
nombre VARCHAR(200) NOT NULL,
precio_base DECIMAL(10,2) NOT NULL,
atributos JSON,
metadata JSON
);
INSERT INTO productos (sku, nombre, precio_base, atributos) VALUES
('LAPTOP-001', 'Laptop Pro', 1299.99,
JSON_OBJECT(
'marca', 'TechCorp',
'specs', JSON_OBJECT('cpu', 'i7', 'ram_gb', 16, 'almacenamiento_gb', 512),
'etiquetas', JSON_ARRAY('laptop', 'negocio', 'portatil')
));
Consultas sobre JSON
SELECT
sku,
atributos->>'$.marca' AS marca,
atributos->>'$.specs.ram_gb' AS ram,
JSON_LENGTH(atributos->'$.etiquetas') AS num_etiquetas
FROM productos;
-- Filtrar por campo JSON
SELECT * FROM productos
WHERE atributos->>'$.marca' = 'TechCorp'
AND CAST(atributos->>'$.specs.ram_gb' AS UNSIGNED) >= 16;
-- Buscar en arrays JSON
SELECT * FROM productos
WHERE JSON_CONTAINS(atributos->'$.etiquetas', '"laptop"');
-- Expandir array a filas con JSON_TABLE
SELECT p.sku, t.etiqueta
FROM productos p,
JSON_TABLE(p.atributos->'$.etiquetas', '$[*]'
COLUMNS (etiqueta VARCHAR(50) PATH '$')
) t;
Índice Multivalor en JSON
CREATE INDEX idx_etiquetas ON productos
((CAST(atributos->'$.etiquetas' AS CHAR(50) ARRAY)));
-- La consulta ahora usa el índice
SELECT * FROM productos
WHERE 'laptop' MEMBER OF (atributos->'$.etiquetas');
Agregación JSON
-- Construir JSON a partir de filas
SELECT
categoria,
JSON_ARRAYAGG(
JSON_OBJECT('id', id, 'nombre', nombre, 'precio', precio_base)
) AS productos
FROM productos
GROUP BY categoria;
-- Actualizar campo específico
UPDATE productos
SET atributos = JSON_SET(atributos, '$.en_oferta', true)
WHERE precio_base > 1000;
MySQL como Document Store (X DevAPI)
const mysqlx = require('@mysql/xdevapi');
const session = await mysqlx.getSession('mysqlx://user:pass@localhost:33060');
const db = session.getSchema('tienda');
const coleccion = await db.createCollection('productos');
await coleccion.add({
sku: 'PHONE-001',
nombre: 'Teléfono Inteligente',
precio: 699.99,
specs: { pantalla: '6.5"', bateria: '5000mAh' }
}).execute();
const resultado = await coleccion
.find('precio < :maximo')
.bind('maximo', 1000)
.fields('sku', 'nombre', 'precio')
.execute();
console.log(resultado.fetchAll());
Validación de Esquema JSON
ALTER TABLE productos
ADD CONSTRAINT chk_atributos
CHECK (
JSON_SCHEMA_VALID(
'{
"type": "object",
"properties": {
"marca": { "type": "string" },
"specs": {
"type": "object",
"required": ["cpu", "ram_gb"]
}
},
"required": ["marca"]
}',
atributos
)
);