OpenStax-CNX module: m18179 1 Traducción de relaciones reflexivas a tablas relacionales ∗ Miguel-Angel Sicilia This work is produced by OpenStax-CNX and licensed under the Creative Commons Attribution License 2.0† Abstract Se introduce el concepto de relación reexiva en el modelado conceptual Entidad-Relación, se explica la traducción a tablas relacionales, y se proporciona un ejemplo de recuperación de relaciones reexivas mediante SQL. 1 Traducción de relaciones conceptuales reexivas a modelo relacional 1.1 Relaciones reexivas En el modelo Entidad-Relación, es posible especicar conjuntos de relaciones que conectan entidades pertenecientes a la misma colección de entidades. A esas relaciones se les suele denominar relaciones reexivas. Por ejemplo, podemos representar con relaciones reexivas la relación jerárquica de jefes y subordinados mediante dos relaciones denidas sobre la colección de entidades ∗ Version 1.1: Nov 4, 2008 12:30 pm -0600 † http://creativecommons.org/licenses/by/2.0/ http://cnx.org/content/m18179/1.1/ EMPLEADOS, como se muestra en la siguiente gura. OpenStax-CNX module: m18179 2 Figure 1 La relación amigos es de tipo muchos a muchos, de modo que las entidades pueden imaginarse como un grafo de relaciones. En este caso consideramos que la relación de amistad es completamente simétrica (aunque esto en la realidad no siempre es así). Por otro lado, la relación jefe de es de tipo uno a muchos, y por tanto tiene estructura de árbol (o bien de un conjunto de árboles, un bosque). 1.2 Traducción Para realizar la traducción hay que proceder como si de una relación entre dos entidades se tratara. De esta manera, en nuestro ejemplo se tienen dos relaciones, de cardinalidades 1:n y n:m, por lo que el modelo relacional quedaría: EMPLEADOS ( NSS , sueldo, nombre, apellido, NSSSupervisor) AMIGOS ( NSSAmigo_A, NSSAmigo_B ) 1.3 Recuperación de las relaciones Para recuperar las relaciones reexivas una vez traducidas a tablas relacionales, es necesario hacer auto-joins (self-joins). Para entender la mecánica, vamos a ver un ejemplo concreto. Tabla EMPLEADOS http://cnx.org/content/m18179/1.1/ OpenStax-CNX module: m18179 3 NSS Nombre Apellidos Sueldo NSSSupervisor 111111 Miguel Sánchez 65.000 null 222222 Pablo Sánchez 55.000 111111 333333 Carmen García 45.000 111111 444444 Luis López 35.000 333333 555555 Pedro Pérez 35.000 222222 666666 Maria Martínez 35.000 444444 777777 Laura López 30.000 444444 888888 José Pérez 30.000 555555 999999 Juan Gómez 25.000 666666 Table 1 Tabla AMIGOS NSSAmigo_A NSSAmigo_B 111111 222222 111111 333333 111111 777777 111111 555555 222222 333333 222222 999999 222222 444444 222222 777777 333333 777777 999999 222222 999999 555555 444444 555555 555555 999999 Table 2 1.3.1 Recuperación de la relación uno a muchos Si queremos obtener una lista de los empleados y la información asociada de sus jefes, tendremos que hacer un auto-join en el que la condición de combinación compara la clave ajena que indica el supervisor con la información original. SELECT E1.NSS, E1.nombre, E1.apellidos, E1.sueldo, E2.nombre as jefe_nom, E2.apellidos as jefe_app FROM empleados AS E1 , empleados AS E2 WHERE E1.NSSSup = E2.NSS http://cnx.org/content/m18179/1.1/ OpenStax-CNX module: m18179 4 El resultado producido es el siguiente: '222222', '333333', '444444', '555555', '666666', '777777', '888888', '999999', La 'Pablo', 'Sanchez', 55.0, 'Miguel', 'Sanchez' 'Carmen', 'Garcia', 45.0, 'Miguel', 'Sanchez' 'Luis', 'Lopez', 35.0, 'Carmen', 'Garcia' 'Pedro', 'Perez', 35.0, 'Pablo', 'Sanchez' 'Maria', 'Martinez', 35.0, 'Luis', 'Lopez' 'Laura', 'Lopez', 30.0, 'Luis', 'Lopez' 'Jose', 'Perez', 30.0, 'Pedro', 'Perez' 'Juan', 'Gomez', 25.0, 'Maria', 'Martinez' sentencia anterior corresponde a un INNER JOIN. Lo que no se ha recuperado son los empleados sin Si queremos que las tuplas de la tabla de la izquierda siempre aparezcan en el resultado, hay que hacer un LEFT JOIN, de modo que nos aseguramos que obtenemos información de todos los emplados. SELECT E1.NSS, E1.nombre, E1.apellidos, E1.sueldo, E2.nombre as jefe_nom, E2.apellidos as jefe_app FROM empleados AS E1 LEFT JOIN empleados AS E2 ON E1.NSSSup = E2.NSS Esa sintaxis es equivalente a LEFT OUTER JOIN. Como resultado, se generará además una tupla adicional: '111111', 'Miguel', 'Sanchez', 65.0, null, null 1.3.2 Recuperación de la relación muchos a muchos Nótese que en la tabla la(Y,X). AMIGOS, no hay información repetida, es decir, si tenemos la tupla (X, Y) no tenemos Para obtener los amigos tenemos que hacer un doble join. SELECT E1.nombre, E1.apellidos, E2.nombre, E2.apellidos FROM amigos AS A, EMPLEADOS AS E1, EMPLEADOS AS E2 WHERE A.NSSAmigo_A = E1.NSS and A.NSSAmigo_B = E2.NSS El resultado de la consulta es el siguiente: 'Miguel', 'Sanchez', 'Pablo', 'Sanchez' 'Miguel', 'Sanchez', 'Carmen', 'Garcia' 'Miguel', 'Sanchez', 'Pedro', 'Perez' 'Miguel', 'Sanchez', 'Laura', 'Lopez' 'Pablo', 'Sanchez', 'Carmen', 'Garcia' 'Pablo', 'Sanchez', 'Luis', 'Lopez' 'Pablo', 'Sanchez', 'Laura', 'Lopez' 'Pablo', 'Sanchez', 'Juan', 'Gomez' 'Carmen', 'Garcia', 'Laura', 'Lopez' 'Luis', 'Lopez', 'Pedro', 'Perez' 'Pedro', 'Perez', 'Juan', 'Gomez' http://cnx.org/content/m18179/1.1/