La programación de bases de datos relacionales ofrece herramientas poderosas para optimizar consultas y almacenar información de manera eficiente. En MySQL, aunque no existen las vistas materializadas como característica nativa, podemos implementar estructuras de datos que emulen su funcionamiento, permitiéndonos evitar la ejecución repetida de consultas complejas y mejorando significativamente el rendimiento de nuestras aplicaciones.
¿Cómo crear estructuras similares a vistas materializadas en MySQL?
Para entender cómo podemos implementar algo similar a una vista materializada en MySQL, primero debemos recordar que una vista regular es simplemente un query que se ejecuta cada vez que lo consultamos. Sin embargo, lo que necesitamos es una tabla permanente que almacene los resultados de una consulta compleja, evitando así el tiempo de procesamiento cada vez que necesitamos esa información.
Comencemos creando una tabla que almacenará los resultados de nuestras consultas:
CREATETABLE ventas_diarias_m (`date`DATENOTNULLUNIQUE,`count`INTEGER, total FLOAT);
Esta tabla simple almacenará tres datos fundamentales: la fecha de la operación, el número de operaciones realizadas en esa fecha y el monto total de dichas operaciones. La columna date será nuestra clave única para evitar duplicados.
Una vez creada la tabla, podemos llenarla con información utilizando un INSERT combinado con un SELECT:
Este comando inserta en nuestra tabla los datos agrupados por fecha, contando las operaciones y sumando los totales. El resultado es una tabla que contiene información histórica organizada de manera eficiente, lista para ser consultada sin necesidad de recalcular estos valores cada vez.
¿Qué son los queries anidados y cómo utilizarlos?
Los queries anidados son una técnica poderosa que nos permite utilizar el resultado de una consulta dentro de otra. Existen dos formas principales en que podemos utilizar esta técnica:
Cuando el query interno devuelve un único valor
Cuando el query interno devuelve una lista de valores
Veamos un ejemplo práctico: supongamos que queremos encontrar todas las entradas en build_products que corresponden a clientes de Argentina y de género masculino.
Utilizando JOIN:
SELECT bp.build_product_id, bp.date_add, bp.total
FROM build_products AS bp
LEFTJOIN builds AS b ON bp.bill_id = b.build_id
LEFTJOIN clients AS c ON b.client_id = c.client_id
WHERE c.country ='AR'AND c.gender ='M'ORDERBY2ASC;
Utilizando queries anidados:
SELECT bp.build_product_id, bp.date_add, bp.total
FROM build_products AS bp
WHERE bp.bill_id IN(SELECT b.build_id
FROM builds AS b
LEFTJOIN clients AS c ON b.client_id = c.client_id
WHERE c.country ='AR'AND c.gender ='M')ORDERBY2ASC;
Ambos enfoques producen exactamente el mismo resultado (98 filas en este caso), pero cada uno tiene sus ventajas en diferentes situaciones. Los queries anidados son particularmente útiles cuando necesitamos actualizar datos basados en condiciones complejas.
¿Cómo actualizar datos utilizando queries anidados?
Los queries anidados son especialmente útiles para actualizar datos basados en cálculos o condiciones complejas. Veamos un ejemplo donde agregamos una columna a la tabla clients para almacenar el número de facturas asociadas a cada cliente:
ALTERTABLE clients ADDCOLUMN bill_count INTEGER;
Ahora, podemos actualizar esta columna utilizando un query anidado:
UPDATE clients AS c
SET bill_count =(SELECTCOUNT(*)FROM bills AS b
WHERE b.client_id = c.client_id
);
Este comando actualiza la columna bill_count para cada cliente con el número exacto de facturas asociadas a ese cliente. La potencia de este enfoque radica en que el query interno se ejecuta una vez por cada fila de la tabla externa, permitiéndonos realizar actualizaciones precisas y personalizadas.
Ventajas de los queries anidados
Los queries anidados ofrecen varias ventajas:
Permiten realizar operaciones complejas que serían difíciles de expresar con JOINs
Son especialmente útiles para actualizaciones y eliminaciones condicionales
Pueden mejorar la legibilidad del código en ciertos casos
Ofrecen flexibilidad para trabajar con subconjuntos de datos
Sin embargo, es importante recordar que no siempre son la mejor opción. En algunos casos, los JOINs pueden ser más eficientes o más claros.
Las técnicas que hemos explorado son fundamentales para optimizar el rendimiento de nuestras bases de datos y construir aplicaciones eficientes. Tanto las estructuras similares a vistas materializadas como los queries anidados nos permiten manipular y acceder a los datos de manera más eficiente, reduciendo la carga en nuestro sistema y mejorando la experiencia del usuario. ¿Has utilizado alguna de estas técnicas en tus proyectos? Comparte tu experiencia en los comentarios.
No tenía ni idea que podía usarse un select en lugar de la subcláusula values para pasarle valores de una columna existente, en éste caso bill_products, a una tabla recién creada, en éste caso ventas_diarias_m.
Por que no ocupar una GUI para no tener que andar cambiando de pantalla solo por que en la terminal no se ve bonito?
Porque usar un GUI muchas veces distrae mucho y además tienes que enseñar a usar el GUI más que los conceptos de la manera más pura que se pueden enseñar. Y porque así trabajo todos los días ;)
Completamente de acuerdo Profesor Alberto, fue mas duda por que en el momento de escribirla me auto decía:" Escribalo en la terminal profe!!" esperando me escuchara jaja. Saludos!
Hola, reciban un saludo me gustaría preguntar el por que al ejecutar la instrucción el where no funciona o no se si hay algún otro problema ya que arroja empty set.
-> where c.country = 'Ar';
Probablemente, por accidente, duplicaste el ciclo FROM... WHERE... , además, en dicha duplicación se borró una parte de FROM bill_products y quedó solamente ill_products.
Por otro lado, te recomiendo revisar WHERE c.country = 'Ar' ya que puede ser que se encuentre en minúsculas 'ar' y por tanto no lo reconocería.
Espero te sirva de ayuda.
Hola Todos, esta esUna consulta con Misma lógica usando INNER JOIN (más legible)mas clara y ordenada.
SELECT bp.bill_product_id,DATE(bp.date_added)AS date_added, bp.totalFROM bill_products AS bp
JOIN bills AS b ON bp.bill_id= b.bill_idJOIN clients AS cl ON b.client_id= cl.client_idWHERE cl.country='ARG'AND cl.gender='F'ORDERBY bp.date_added;
Ventaja: más directo, evita la subconsulta y es más claro en la intención: "quiero productos de facturas cuyos clientes cumplen X".
SIEMPRE ES MAS RAPIDO UN JOIN NO?
También de forma similar se puede hacer con EXISTS
SELECT bp.bill_product_id, bp.date_added, bp.totalFROM bill_products AS bp
WHEREEXISTS(SELECT1FROM bills AS b
WHERE b.bill_id= bp.bill_idANDEXISTS(SELECT1FROM clients AS c
WHERE c.client_id= b.client_idAND c.country='AR'AND c.gender='m'))ORDERBY2ASC;
Interesante colega...
Consulta, leí que es más eficiente hacer los cruces que hacer las queries anidadas? Es tan así o es en casos particulares de tablas con muchos registros?
Cuando se habla de "materializado" en el contexto de bases de datos, especialmente en MySQL, se refiere a una estructura que permite almacenar los resultados de una consulta (query). Aunque MySQL no tiene vistas materializadas de forma nativa, el concepto implica crear una tabla que contenga los resultados de una consulta, permitiendo acceder a la información de manera más rápida que al ejecutar el query cada vez. Esto es útil para mejorar el rendimiento al evitar consultas largas y complejas.
Saludos. Nada mas quería comentar un errorcillo de sintaxis dentro del resumen de la clase. En la sección de queries anidados, en ambos queries se está utilizando la palabra build en vez de bill al especificar las tablas y las columnas.
En los recursos han estado mal nombradas las tablas: bill.. es correcto, no es build.