La generación de columnas en MySQL es una herramienta poderosa que permite transformar y manipular datos de manera eficiente. Estas columnas pueden ser virtuales o almacenadas, dependiendo de nuestras necesidades específicas. Dominar esta funcionalidad nos permite crear bases de datos más inteligentes y optimizadas para aplicaciones web modernas.
¿Cómo crear slugs SEO-friendly con MySQL?
Cuando desarrollamos aplicaciones web, frecuentemente necesitamos crear URLs amigables para el SEO. Estas URLs, conocidas como "slugs", suelen derivarse del título o nombre de un producto, artículo o recurso. En lugar de utilizar un lenguaje de programación externo para generar estos slugs, podemos aprovechar las funciones de MySQL para crearlos directamente en nuestra base de datos.
Observemos nuestra tabla de productos:
SELECT name, slug FROM products LIMIT10;
El slug almacenado en la tabla convierte espacios en guiones, cambia mayúsculas a minúsculas y elimina caracteres especiales. Por ejemplo, "Heavy Duty Steel Computer" se convierte en "heavy-duty-steel-computer".
¿Cómo transformar texto con funciones de MySQL?
Para generar nuestro propio slug, necesitamos aplicar varias transformaciones al texto:
Convertir a minúsculas: Utilizamos la función LOWER()
SELECT name, LOWER(name)AS generated FROM products LIMIT10;
Reemplazar espacios por guiones: Podemos usar expresiones regulares con REGEXP_REPLACE()
SELECT name, REGEXP_REPLACE(LOWER(name),' ','-')AS generated FROM products LIMIT10;
Eliminar caracteres especiales: Reemplazamos todo lo que no sea alfanumérico en inglés
SELECT name, REGEXP_REPLACE( REGEXP_REPLACE(name,'[^a-z[:space:]]','_'),'[:space:]','-')AS generated
FROM products LIMIT10;
Esta expresión regular reemplaza cualquier carácter que no esté entre a-z y no sea un espacio por un guion bajo, y luego reemplaza los espacios por guiones.
¿Columna virtual o almacenada?
Una vez que tenemos nuestra expresión para generar slugs, debemos decidir si implementarla como una columna virtual o almacenada:
Columna virtual: Se calcula cada vez que se consulta
Columna almacenada: Se calcula y almacena cuando se inserta o actualiza el registro
Para decidir, debemos considerar la frecuencia de cambio de los datos. En el caso de los slugs, estos solo cambian cuando cambia el nombre del producto, por lo que una columna almacenada es más eficiente:
Con esta instrucción, creamos una nueva columna que:
Se genera automáticamente basada en el nombre del producto
Se almacena físicamente en la tabla
Se actualiza solo cuando cambia el nombre del producto
Podemos verificar que funciona correctamente actualizando un nombre de producto:
UPDATE products SET name ='Hola, cómo estás?'WHERE product_id =9;SELECT product_id, name, slug, slug_generated FROM products LIMIT10;
Veremos que slug_generated se actualiza automáticamente con el valor "hola_como_estas-".
¿Qué otras funciones de manipulación de texto ofrece MySQL?
MySQL proporciona una amplia gama de funciones para manipular texto:
LENGTH(): Obtiene la longitud de una cadena
SUBSTRING(): Extrae una parte de una cadena
CONCAT(): Combina dos o más cadenas
TRIM(): Elimina espacios al inicio y final
REPLACE(): Reemplaza todas las ocurrencias de una subcadena
La potencia de estas funciones radica en su velocidad de ejecución. Como pudimos observar, procesar 2,358 registros tomó apenas 0.01 segundos, lo que demuestra la eficiencia de MySQL para estas operaciones.
Las columnas generadas nos permiten mantener la consistencia de los datos y evitar cálculos redundantes en nuestra aplicación. Además, al estar integradas en la base de datos, garantizan que todos los clientes que accedan a los datos obtengan los mismos resultados procesados.
El dominio de estas técnicas de manipulación de datos directamente en MySQL puede mejorar significativamente el rendimiento y la mantenibilidad de nuestras aplicaciones. ¿Has utilizado columnas generadas en tus proyectos? Comparte tu experiencia en los comentarios.
update products set name ="Heávy Dity Stel Co'mputer" where product_id =1 limit 1;update products set name ="Practicäl Copper Beñch" where product_id =2 limit 1;update products set name ="Intèlligent Grañite Hat" where product_id =3 limit 1;update products set name ="Enormóus Silk Clock" where product_id =4 limit 1;```update products set name ="Heávy Dity Stel Co'mputer" where product\_id =1 limit 1; update products set name ="Practicäl Copper Beñch" where product\_id =2 limit 1; update products set name ="Intèlligent Grañite Hat" where product\_id =3 limit 1; update products set name ="Enormóus Silk Clock" where product\_id =4 limit 1;
Hola Chicos.
Esta es una forma mas practica y optima para hacer el UPDATE con mas amplitud de caracters especiales : "$$#$]Ñ[{}] en mis products.name.
ALTERTABLE products
ADDCOLUMN own_generated_slug VARCHAR(125)GENERATEDALWAYSAS(LOWER(TRIM(BOTH'-'FROMREGEXP_REPLACE(REGEXP_REPLACE( product_name,'[^a-zA-Z0-9[:space:]]',''-- elimina todo lo que NO sea letra, número o espacio
),'[[:space:]]+','-'-- reemplaza espacios múltiples por un solo guion
))))STORED;
[[:space:]]+
→ reemplaza cualquier cantidad de espacios por un solo guion -.
TRIM(BOTH '-' FROM …)
→ elimina guiones sobrantes al inicio o final.
LOWER()
→ convierte todo a minúsculas (slugs deben ser lowercase).
STORED
→ se guarda físicamente, se recalcula automáticamente si cambias product_name.
Sin embargo, parece un aterrador callbackHell de JS, por tanto.
Aquí tienes una versión más limpia, elegante y eficiente de tu expresión SQL para generar un slug en base al nombre del producto (name) con una sola expresión regular, evitando el infierno de funciones anidadas:
ALTERTABLE products
ADDCOLUMN own_generated_slug VARCHAR(125)AS(LOWER(REGEXP_REPLACE(REGEXP_REPLACE( name,'[^a-zA-Z0-9]+',--Reemplaza todo lo que no sea letras o números por un guion
'-'),'-+',--Si hay varios guiones seguidos, deja solo uno
'-')))STORED;
[^a-zA-Z0-9]+ → Captura cualquier conjunto de caracteres que no sean letras ni números, incluyendo espacios, tildes, ñ, comillas, etc., y los reemplaza por un guion -.
'-+' → Si se forman varios guiones seguidos, los reduce a uno solo.
LOWER() → Convierte todo a minúsculas para mantener la consistencia de URLs.
STORED → Guarda el valor generado automáticamente en la base de datos.
Si deseas además eliminar acentos (á → a, ñ → n, ü → u), puedes extenderlo un poco usando COLLATE utf8mb4_general_ci o la función unaccent() si estás en PostgreSQL.
En MySQL puro, eso se puede lograr usando la función REPLACE() encadenada para cada vocal acentuada, pero te recomiendo dejar la limpieza principal al backend (por ejemplo, con PHP o JavaScript) para los acentos.
Aprender expresiones regulares para que te facilite la vida.
Excelente clase
Creación de Slugs SEO
Limpieza: Elimina acentos y caracteres especiales para asegurar compatibilidad total en navegadores.
Normalización: Convierte el texto a minúsculas y sustituye espacios por guiones medios para mejorar la legibilidad.
Automatización en Base de Datos
Funciones MySQL: Implementa la lógica directamente en el motor de datos para garantizar consistencia absoluta en cada inserción.
¿Por qué el profesor utiliza dos [:space:]?, mi lógica es utilizar un único regexp_replace con la condición[^a-zA-Z0-9]+ y así cualquier cosa que no sea un letra o número será convertida por el '-'-
el porqué es simple, una cosa es plantear una solución en tiempo real, mientras estas generando contenido y otra es estar escuchandolo solamente pausarlo, pensar otra posible solución tomarse el tiempo, así sea corto.