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