MySQL es un gran motor de bases de datos y pese a ser uno de los más usados en la red, no se le aprovecha todo su potencial. Hoy Hector nos comentaba como pulir nuestro server MySQL para conseguir optimizar el rendimiento de nuestro servidor. De esta forma nos acercabamos un poco más a la parte más técnica del motor de base de datos.
Ahora vamos a ver un herramienta que el propio lenguaje SQL sobre MySQL nos permite facilitarnos la vida a todos los que trabajamos con este tipo de bases de datos, la implementación RegExp, o expresiones regulares.
Las expresiones regulares
Las expresiones regulares son algo que siempre se me ha atragantado, debe de ser por el concepto abstracto del que se componen o por que tampoco de dedicaba el tiempo que se merecian. Pero fue pasando el tiempo y poco a poco, por motivo laborales no hubo más remedio que plantarles cara, y apesar de ser algo que produce una curva de aprendizaje algo más elevada que usar botijo, el resultado es abrumador.
Si eres un usuario de Linux, medio-avanzado, serás un experto en ellas ya que grep (la herramienta por excelencia de Linux) junto las expresiones regulares son de lo más útil que te puedas imaginar.
En definitiva, llamamos expresión regular a un conjunto de caracteres que forman un patrón al que le aplicaremos una serie de elementos y comprobaremos si dicho patrón concuerda con alguno de los elementos aplicados.
En resumen, un sistema muy util para buscar coincidencias en varios elementos.
Expresiones Regulares y MySQL
Partiendo de la definición anterior, sacamos que se trata de buscar, y ¿que mejor para buscar que MySQL?
Cualquier motor de bases de datos que implemente SQL, usará una proporción descomunal de SELECT
(consultas) frente a INSERT INTO
(insercción de datos), por este motivo nacen las expresiones regulares para este lenguaje (SQL). Con ellas podemos definir patrones para perfeccionar las busquedas en nuestras bases de datos.
Veamos unos ejemplos:
Patrón básico
SELECT prod_name FROM products WHERE prod_name REGEXP '1000' ORDER BY prod_name;
Esta expresión REGEXP '1000'
, no filtrará todos los resultados de la tabla products
en los que el campo prod_name
contenga el valor 1000
.
Como podemos ver esto es fácil, pero la cosa se puede complicar.
Patrón con punto
SELECT prod_name FROM products WHERE prod_name REGEXP '.000' ORDER BY prod_name;
En este ejemplo ya vemos como la expresión regular empieza a usar carácteres «raros». Estos carácteres tienen un valor preestablecido para hacer las busquedas más genéricas, de modo que en este ejemplo obtendremos todas las filas de la tabla cuyo prod_name contenga algún valor como 1000
, 2000
, 3000
,…pero tambien x000
, d000
,…
De aqui entonces podemos sacar que el (.
) es el un carácter especial que indica que puede ser reemplazado por cualquier otro carácter. Pero tambien podemos necesitar que dichos carácteres se repitan un número definido o no de veces.
* |
0 o más veces |
+ |
1 o más veces |
? |
0 o 1 |
{n} |
n veces |
{n,} |
n o más veces |
{n,m} |
Se especifica un rango entre n y m |
Evidentemente estos carácteres tambien son carácteres válidos para nuestras busquedas y pueden formar parte de nuestros datos, por ese motivo hemos de escaparlos. Para ello usaremos la barra invertida doble.
SELECT vend_name FROM vendors WHERE vend_name REGEXP '\\.' ORDER BY vend_name;
De esta forma obtendremos los resultados que contengan un punto en su campo vend_name
. ¿Y como se escapa la barra invertida? Pues como si se tratara de otro carácter a escapar (\\\
).
Patrón con inicio y fin
SELECT prod_name FROM products WHERE prod_name REGEXP '^1000' ORDER BY prod_name;
Otro carácter especial que debemos conocer es el de (^
) que se encarga de indicar que el partrón se inicia al iniciar la línea, de esta forma obtendremos resultados como «1000 caballos ...
» pero no «los 1000 caballos...
«.
Pero no solo podemos controlar el inicio del texto, tambien tenemos operadores para depurar más nuestro patrón.
^ |
Inicio del texto |
$ |
Fin del texto |
[[:<:]] |
Inicio de la palabra |
[[:>:]] |
Fin de la palabra |
Patrón condicional
SELECT prod_name FROM products WHERE prod_name REGEXP '1000|2000' ORDER BY prod_name;
La pipe (|
) indica que el patrón puede estar formado por 1000
o por 2000
, y nada más.
Patrón con varios carácteres condicionales
SELECT prod_name FROM products WHERE prod_name REGEXP '[123] Ton' ORDER BY prod_name;
[123]
nos indica que en la posición en la que se encuentra únicamente podrá haber un 1
, un 2
o un 3,
y ningún carácter más. Esto es muy util para controlar rangos de carácteres, por ejemplo solo números [0-9]
o solo minúsculas [a-z]
.
Para mejorar el trabajo de los desarrolladores se crearon una serie de variables para definir algunos de estos patrones de forma cómoda y rápida.
[:alnum:] |
[a-zA-Z0-9] |
[:alpha:] |
[a-zA-Z] |
[:blank:] |
[\\t ] |
[:cntrl:] |
Carácteres de control (ASCII 0 hasta 31 y 127) |
[:digit:] |
[0-9] |
[:graph:] |
[:print:] sin contar el espacio |
[:lower:] |
[a-z] |
[:print:] |
Carácteres imprimibles |
[:punct:] |
Carácteres no comprendidos en [:alnum:] ni en [:cntrl:] |
[:space:] |
[\\f\\n\\r\\t\\v ] |
[:upper:] |
[A-Z] |
[:xdigit:] |
[a-fA-F0-9] |
Conclusión
Conociendo esto podemos definir un patrón lo más ajustado posible a nuestra busqueda, haciendo que nuestros resultados sean los que realmente queremos obtener. Un poco de paciencia y tiempo y cualquiera puede controlar esta tran propiedad de MySQL.
3 comentarios, 3 referencias
+
#