Sie sind auf Seite 1von 10

Tutorial Mysql Relaciones entre tablas y su integridad referencial

Muchos habreis tenido problemas al crear tablas relacionadas con MySql, pero de verdad que es bastante sencillo, solo hay que tener en cuenta una serie de premisas:

Las tablas que se van a relacionar tienen que ser tipo InnoDb(InnoDB es el primer tipo de tabla que permite definir estricciones de claves forneas para garantizar la integridad de los datos). Usar sintaxis FOREIGN KEY (campo_fk) REFERENCES nombre_tabla(nombre_campo) Crear un gndice en el campo que ha sido declarado clavefornea

Es necesario el uso de ndices para que la verificacin de las claves forneas sea ms rpida. Vamos a ver un ejemplo de una definicin de 2 tablas relacionadas. Clientes y privilegios: PLAIN TEXT MySQL: 1. 2. 3. 4. 5. CREATE TABLE clientes ( id_cliente INT NOT NULL AUTO_INCREMENT, nombre VARCHAR(30), PRIMARY KEY (id_cliente)

6. ) TYPE = INNODB; 7. 8. CREATE TABLE privilegios 9. ( 10. id_privilegio INT NOT NULL AUTO_INCREMENT, 11. id_cliente INT NOT NULL, 12. privilegio INT(2), 13. PRIMARY KEY(id_privilegio), 14. INDEX (id_cliente), 15. FOREIGN KEY (id_cliente) REFERENCES clientes(id_cliente) 16. ) TYPE = INNODB; De esta manera estamos relacionando la tabla clientes y privilegios por el campo id_cliente. La clave fornea (FOREIGN KEY) y la Referenciada tienen que tener tipos de datos similares para que puedan ser comparadas sin la necesidad de hacer una conversin de tipos. Ahora ya tenemos las tablas relacionadas y seguro que os haceis la siguiente pregunta: "Cmo inserto registros en las tablas que tengan claves forneas (FOREIGN KEYS)?" Bueno, esta pregunta realmente nos la podemos hacer para cuando se inserta un registro, se borra o se actualiza, ya que en las tres lo tendremos que tener en cuenta. Ahora vamos a insertar algn registro para verificar que todo est correcto: PLAIN TEXT MySQL: 1. INSERT INTO clientes VALUES (1, 'Pedro Picapiedras'); 2. INSERT INTO clientes VALUES (2, 'Pablo Marmol'); 3. INSERT INTO clientes VALUES (3, 'Ana Botella'); PLAIN TEXT MySQL: 1. INSERT INTO privilegios VALUES (1,1,10); 2. INSERT INTO privilegios VALUES (2,3,05); 3. INSERT INTO privilegios VALUES (3,2,01); Nota: No me pregunteis porque he puesto Ana Botella dentro de esta categora de clientes .

Hasta ahora ha ido todo bien, pero que pasara si intentamos insertar un registro en la tabla "privilegios" en el que nos refiramos a un cliente que no exista en la tabla clientes?, vamos a probarlo: PLAIN TEXT MySQL: 1. INSERT INTO privilegios VALUES (4,5,10); Pues s nos tiene que devolver un error tal como este: "ERROR 1216: Cannot add or update a child row: a foreign key constraint fails" La razn es bastante evidente, estamos intentando insertar un registro en la tabla privilegios sobre un cliente "id_cliente=5", y hasta el momento no existe. Ahora vamos a intentar eliminar un registro de la tabla clientes: PLAIN TEXT MySQL: 1. DELETE FROM cliente WHERE id_cliente=3; Debido a que tenemos la restriccin de la clave fornea no permitir eliminar el registro puesto que se hace referencia a l en la tabla "privilegios", por lo tanto Mysql nos devolvera el siguiente error: "ERROR 1217: Cannot delete or update a parent row: a foreign key constraint fails" Para eliminar este tipo de registros con claves forneas existen lo que se llama eliminacin en CASCADA, en la que todos los registros relacionados se eliminan segn las relaciones de claves forneas. Para llevar a cabo una eliminacin de todos los registros relacionados por las claves forneas en distintas tablas se usa la funcion "ON DELETE CASCADE". Si se especifica ON DELETE CASCADE, y una fila en la tabla padre es eliminada, entonces se eliminarn las filas de la tabla hijo cuya clave fornea sea igual al valor de la clave referenciada en la tabla padre. Esta accin siempre ha estado disponible en MySQL. Fuente: Mysql-hispano.org Veamos un ejemplo de eliminacin en cascada: PLAIN TEXT MySQL:

1. ALTER TABLE privilegios ADD FOREIGN KEY(id_cliente) 2. REFERENCES cliente(id_cliente) ON DELETE CASCADE; Con esta sentencia, ya tendremos dispuesta la tabla para que se pueda eliminar en cascada. Por lo tanto si queremos eliminar ahora al cliente "Ana Botella", tan slo tendriamos que ejecutar lo sisguiente: PLAIN TEXT MySQL: 1. DELETE FROM cliente WHERE id_cliente=3; Si haceis una consulta ahora en las dos bases de datos, "clientes" y "privilegios", vereis como se ha eliminado "Ana Botella" de las dos tablas. Al igual que la eliminacin tambin podemos actuar en cascada con las actualizaciones con la sentencia "ON UPDATE CASCADE". Esto es todo, espero ayudaros a entender un poco mejor la integridad referencial en Mysql y la relacin entre tablas.

INNER JOIN para unir Tablas


uy bien, aprendices del Sql, hoy hablaremos de la instruccin INNER JOIN. Muy til para casos concretos. Primero de todo vamos a crear una situacin hipottica: Imaginemos que tenemos que hacer una web que contiene unos artculos en referencia a comentarios de novelas, y que son doce escritores de prestigio los que van introduciendo esas crticas. Lo normal y ms bsico para un programador sera pensar en base de datos y lenguaje dinmico. Una buena eleccin podra ser trabajar con PHP y MySql (aunque para lo que voy a decir basta con una base de datos de tipo Sql). Lo primero que nos viene a la mente es: har una tabla, llammosla criticas. En ella almacenaramos cada artculo. Los campos bsicos seran ID, Libro, Escritor (del libro, nunca confundir con el autor de la crtica), Editorial, ao y Autor de la crtica. Pero y si quisiramos, como es normal, poner en la misma crtica una referencia al autor de la critica, anque slo sea un pequeo texto biogrfico? Tendramos que repetir un mismo texto repetidas veces en la base (la biografia de doce autores en, pongamos 150 registros) y si quisieramos modificarlo y hubiera 70 entradas con ese autor eso sera un desastre.

Entonces queda claro que hay que hacer una referencia a otra tabla que contenga a los autores, con sus respectivos datos. La tabla autores. Cada autor tendra su ID, su nombre y su biografa, adems de otros datos como webpage, e-mail, bibliografa Algunos diran: pues fcil, haces dos querys a la base. en uno le dices 1. SELECT * FROM criticas WHERE ID =37 y en otra 1. SELECT * FROM autores WHERE where qu? tendras que sacar una variable de sql a php, otra vez a sql Nada! Si alguien sugiere eso desconfiad de l y de su familia (es broma ;D) existe un mtodo sencillo y eficaz: el INNER JOIN Tan sencilla es la sentencia como:

1. SELECT * FROM criticas INNER JOIN autores ON criticas.autor = autores.id WHERE criticas.id=7 De esta forma estamos uniendo las dos tablas, cada vez que en criticas el autor sea n, en autores se unir su correspondiente fila, con id=n. Traduciendo al espaol la sentencia dice exactamente: SELECCIONA TODOS LOS CAMPOS UNIENDO criticas CON autores DONDE el campo autor de la tabla criticas SEA IGUAL A el campo id de la tabla autores EN EL REGISTRO EN QUE el id de criticas sea 7 En definitiva, el inner join une dos tablas, donde encajan un campo de una con el mismo de la otra. A partir de ahora las tablas se hacen ms manejables y flexibles.

INNER JOIN: Consulta Mysql para Unir Tablas Relacionadas

Supongamos que tenemos una Tabla Mysql llamada Empresas y otra tabla Servicios. Y nos interesa mostrar en pantalla los servicios que brinda cada empresa, considerando que cada fila de la tabla Servicios tiene un valor asociado a la empresa que pertenece. (ver el siguiente grafico)

Cmo listar todas las empresas y sus servicios correspondiente? Lo hacemos utilizando INNER JOIN mediante la siguiente Consulta Mysql:
1select Empresas.Nombre,Servicios.Servicio 2 3
from Empresas inner join Servicios on Servicios.IdEmpresa=Empresas.Id;

Ver resultado de esta consulta Mysql INNER JOIN Nota 1:: Como se puede observar en el resultado, la empresa YouTube queda afuera del listado. El motivo es que no tiene ningn servicio asociado en la tabla SERVICIOS (no existe servicio que tenga IdEmpresa=3).

Si quisieramos listar todas las empresas, independientemente que tengan servicios o no, debemos utilizar la Consulta Mysql LEFT JOIN

LEFT JOIN: Consulta Mysql para Unir Tablas Relacionadas

La consulta Mysql LEFT JOIN devuelve todas las filas de la tabla citada en la clusula FROM y sus filas vinculadas en la tabla citada dentro de la clusula LEFT JOIN (incluyendo aquellas filas que no tengan filas vinculadas). Vayamos a la prctica! Cuando analizamos el ejemplo de INNER JOIN en Mysql tenamos el siguiente esquema de tablas:

Al efectuar un INNER JOIN entre la tabla Empresas y la tabla Servicios, observbamos que la empresa Youtube.com (Id=3) quedaba fuera del listado resultado puesto que no existe ninguna fila en la tabla Servicios con IdEmpresa=3.

En el caso del ejemplo, LEFT JOIN nos sirve para listar TODAS las empresas y sus servicios correspondientes. Las empresas que no tienen ningn servicio tambin formarn parte del resultado. (en el caso de INNER JOIN, las empresas que no tienen servicio quedaban afuera). Revisemos cmo quedara el cdigo fuente PHP de nuestra consulta Mysql LEFT JOIN:
$consulta_mysql="select Empresas.Nombre,Servicios.Servicio from Empresas

left join Servicios on Empresas.Id=Servicios.IdEmpresa"; $resultado_consulta_mysql=mysql_query($consulta_mysql,$conexion);

El resultado sera:

Siguiendo el ejemplo, cmo podramos listar todos los servicios y las empresas que lo brindan, incluyendo los servicios que no son brindados por ninguna empresa? Lo hacemos a travs de la consulta Mysql RIGHT JOIN que funciona similar a LEFT JOIN pero en viceversa. Es decir, se listan todas las filas de la tabla Mysql citada en la clusula RIGHT JOIN, incluyendo aquellas que no tienen ninguna fila vinculada en la tabla citada dentro de la clusula FROM. La consulta Mysql quedara: 1$consulta_mysql="select Empresas.Nombre,Servicios.Servicio from Empresas 2 right join Servicios on 3Empresas.Id=Servicios.IdEmpresa"; 4$resultado_consulta_mysql=mysql_query($consulta_mysql,$conexion); El resultado sera:

Das könnte Ihnen auch gefallen