Hoy algo de teoría. Como sabemos, el lenguaje estándar para realizar consultas en bases de datos es el SQL (Structured Query Language). Este lenguaje permite definir y manipular bases de datos relacionales, que son las bases de datos con las que solemos trabajar (como MySQL, Oracle, SQL Server y demás). Hay otro tipo de bases de datos que no son relacionales, pero su uso a día de hoy es tremendamente minoritario.
En una base de datos relacional la información está estructurada en forma de relaciones (ojo, no confundirse, en este ámbito ‘relación’ equivale a lo que habitualmente llamamos ‘tabla’) dando lugar a lo que se conoce como modelo relacional. En este modelo relacional las consultas se pueden llevar a cabo con lenguajes relacionales de dos tipos:
1) Lenguajes basados en álgebra relacional, que se inspira en la teoría de conjuntos para ir construyendo paso a paso el procedimiento a seguir para obtener los datos deseados. Estos lenguajes son lenguajes, pues, procedimentales.
2) Lenguajes basados en el cálculo relacional, que se basa en el cálculo de predicados de la lógica matemática. Estos lenguajes no describen un procedimiento y por tanto se les llama lenguajes declarativos (no procedimentales).
SQL es un lenguaje mixto, ya que incluye temas de álgebra relacional y otros de cálculo relacional, aunque predominan estos últimos, por lo que se considera un lenguaje declarativo. No obstante, hoy vamos a ver algunas pinceladas básicas de álgebra relacional.
Para especificar una consulta en álgebra relacional hay que ir siguiendo una serie de pasos que sirven para ir construyendo nuevas relaciones (recordemos: análogas a las tablas) a partir de las relaciones existentes. En estos pasos se utilizan las operaciones del álgebra relacional, que resumidas de un modo muy escueto son las siguientes.
Se trata de una operación que nos facilita trabajar con relaciones cambiándoles el nombre a ellas o a sus atributos. Así…
R (h) := RelacionConNombreOriginal (AtributoConNombreOriginal)
…renombra la relación a ‘R’ y uno de sus atributos a ‘h’ (del mismo modo que relaciones vienen a ser lo que habitualmente llamamos tablas, atributos vienen a ser lo que llamamos campos o columnas en esas tablas).
Se trata de generar una nueva relación juntando todas las tuplas (tuplas = registros) de las dos relaciones que intervienen en la unión. Está claro que las dos relaciones deberán tener estructuras semejantes. Además, como en una relación (como en una tabla) no puede haber tuplas (registros) duplicadas, si al unirlas se da alguna duplicidad, se elimina directamente. Se denota con…
R := T U S
…donde ‘U’ representa el símbolo de unión y ‘T’ y ‘S’ son las relaciones de partida.
Se trata de generar una nueva relación con las tuplas que aparecen a la vez en las dos relaciones que intervienen en la intersección. También aquí las dos relaciones deberán tener estructuras semejantes. Se denota con…
R := T (U) S
…donde ‘(U)’ pretende ser el símbolo de intersección (’U’ invertida) que no sé cómo representar aquí en el blog y ‘T’ y ‘S’ son las relaciones de partida.
Se trata de generar una nueva relación con las tuplas que aparecen en una primera relación pero no en una segunda. Nuevamente ambas relaciones deben tener estructuras semejantes. Se denota con…
R := T - S
…donde ‘T’ y ‘S’ son las relaciones de partida.
Se trata de generar una nueva relación combinando cada una de las tuplas de una primera relación con cada una de las tuplas de una segunda relación. Así pues la relación resultante tendrá tantos atributos como la suma de los atributos de cada una de las relaciones de partida. Y tendrá tantas tuplas como el producto de tuplas de ambas relaciones. Se denota con…
R := T x S
…donde ‘T’ y ‘S’ son las relaciones de partida.
Se trata de generar una nueva relación con un subconjunto de las tuplas de la relación de partida. Para ello es preciso expresar alguna condición que las tuplas deberán cumplir para formar parte de la nueva relación. Se denota con…
R := T(C)
…donde ‘T’ es la relación de partida y ‘C’ la condición (puede ser compuesta) que deben cumplir las tuplas de ‘T’ para formar parte de ‘R’.
Se trata de generar una nueva relación con sólo algunos de los atributos de los que consta la relación de partida. Se denota con…
R := T [A1, A2, A3...]
…donde ‘T’ es la relación de partida y las ‘A’ representan los atributos que se quieren trasladar a la relación resultante ‘R’.
Se trata de generar una nueva relación a partir de un producto cartesiano entre dos relaciones de partida, con la salvedad que sólo formarán parte de la nueva relación las tuplas resultantes del producto que cumplan unas determinadas condiciones de igualdad entre atributos. Dios, suena fatal… pero es simplemente un JOIN. Se denota con…
R := T [B] S
…donde ‘T’ y ‘S’ son las relaciones de partida y ‘B’ es el conjunto de condiciones.
Igual que la combinación, sólo que no es necesario especificar las condiciones ‘B’ puesto que se asume que los atributos que se quieren igualar son los que se llaman igual en las dos relaciones de partida. Se denota con…
R := T * S
…donde ‘T’ y ‘S’ son las relaciones de partida.
Expresado así todo ello suena bastante complejo, la verdad. Pero si conocemos algo de SQL y hemos ido identificando las instrucciones veremos que es mucho más sencillo de lo que parece. Los renombramientos vienen a ser alias, las uniones vienen a ser UNIONs, las selecciones son SELECT * con
cláusulas WHERE, las proyecciones son SELECT con una selección de campos, etc.
Vamos a ver ahora un ejemplo interesante de cómo se construye una consulta con álgebra relacional. Imaginemos que tenemos una relación con las siguientes tuplas (voy a representarlo como tabla con registros para que resulte más familiar):
| biblioteca |
+-------+---------+
| libro | paginas |
+-------+---------+
| AAA | 125 |
| BBB | 250 |
| CCC | 300 |
| DDD | 105 |
+-------+---------+
Si en SQL quisiéramos saber cuál es el menor número de páginas nos bastaría con hacer…
FROM biblioteca;
Y si quisiéramos saber cuál es el libro con ese menor número de páginas tendríamos que hacer…
FROM biblioteca
WHERE paginas = (SELECT MIN(paginas) FROM biblioteca);
¿Pero cómo conseguimos encontrar esto con álgebra relacional donde NO tenemos una maravillosa función MIN()? Tenemos que hacerlo por pasos, más o menos así:
Obtener una relación sólo con los números de páginas.
R1 := biblioteca [paginas]
| paginas |
+---------+
| 125 |
| 250 |
| 300 |
| 105 |
+---------+
Renombrar esta relación para poder llevar a cabo el siguiente paso. Podríamos haberlo hecho directamente en el paso 1, pero así queda más claro.
R2 (pags) := R1 (paginas)
| pags |
+------+
| 125 |
| 250 |
| 300 |
| 105 |
+------+
Llevar a cabo una combinación entre ‘biblioteca’ y la recién obtenida ‘R2′ estableciendo como condición que ‘paginas’ sea mayor que ‘pags’.
R3 := biblioteca [paginas > pags] R2
| libro | paginas | pags |
+-------+---------+------+
| AAA | 125 | 105 |
| BBB | 250 | 125 |
| BBB | 250 | 105 |
| CCC | 300 | 125 |
| CCC | 300 | 250 |
| CCC | 300 | 105 |
+-------+---------+------+
Como vemos, hemos obtenido una relación donde aparecen todas las combinaciones en que ‘paginas’ tiene un valor superior a algún valor de ‘pags’. En esa relación tenemos pues todos los valores de ‘paginas’ que son mayores que algún otro valor de ‘pags’, y por tanto sólo faltan los valores de ‘paginas’ que no son mayores a ningún otro valor de ‘pags’ (o sea, los valores mínimos).
Hacer una proyección para quedarnos sólo con los valores de ‘paginas’.
R4 := R3 [paginas]
| paginas |
+---------+
| 125 |
| 250 |
| 300 |
+---------+
Efectuar una diferencia entre los números de páginas de la relación original (lo tenemos en ‘R1′) y los que acabamos de obtener.
R5 := R4 - R1
| paginas |
+---------+
| 105 |
+---------+
¡Bingo! Ya tenemos el valor mínimo de páginas… vamos ahora a terminar encontrando el título del libro con el menor número de páginas…
Realizar una combinación natural entre la relación original y esta última.
R6 := biblioteca * R5
| libro | paginas |
+-------+---------+
| DDD | 105 |
+-------+---------+
Y para obtener el título del libro… una última proyección.
R7 := R6 [libro]
| libro |
+-------+
| DDD |
+-------+
Así pues, vemos que para llevar a cabo consultas con álgebra relacional debemos seguir una técnica procedimental en que vamos marcando los pasos que hay que ir siguiendo (haz esto y hazlo así). En cambio con SQL no necesitamos hacerlo de ese modo, ya que como hemos comentado al principio del post SQL es un lenguaje declarativo (haz esto, no me importa cómo lo hagas).
Nunca está de más tener algunas nociones de teoría de bases de datos, ¿no? ![]()
Últimos comentarios
RSS