Foros del Web » Programación para mayores de 30 ;) » Bases de Datos General » Mysql »

Problemas creando relación M:N

Estas en el tema de Problemas creando relación M:N en el foro de Mysql en Foros del Web. Hola, Estoy intentando relacionar dos tablas, jugadores y equipos, una relación M:N Para esto he creado una nueva tabla Equipo_Jugadores. Abajo está el sql para ...
  #1 (permalink)  
Antiguo 26/07/2011, 14:01
 
Fecha de Ingreso: febrero-2010
Mensajes: 52
Antigüedad: 14 años, 2 meses
Puntos: 3
Problemas creando relación M:N

Hola,
Estoy intentando relacionar dos tablas, jugadores y equipos, una relación M:N
Para esto he creado una nueva tabla Equipo_Jugadores. Abajo está el sql para crearlas, las he diseñado con Workbench, cuando ejecuto el sql en phpmyadmin, me aparece el siguiente error:

MySQL ha dicho:
#1005 - Can't create table 'futbol.equipo_jugadores' (errno: 121)

Muchas gracias, si alguien me puede ayudar.


----------------TABLAS--------------

CREATE TABLE IF NOT EXISTS `futbol`.`Jugadores` (
`idJugador` INT UNSIGNED NOT NULL AUTO_INCREMENT ,
`equipo` INT NULL ,
`nombre` VARCHAR(45) NULL ,
`apellido` VARCHAR(45) NULL ,
PRIMARY KEY (`idJugador`) ,
UNIQUE INDEX `idJugadores_UNIQUE` (`idJugador` ASC) ,
INDEX `equipo` (`equipo` ASC) ,
CONSTRAINT `equipo`
FOREIGN KEY (`equipo` )
REFERENCES `futbol`.`Equipo_Jugadores` (`equipo` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;


CREATE TABLE IF NOT EXISTS `futbol`.`Equipos` (
`idEquipo` INT UNSIGNED NOT NULL AUTO_INCREMENT ,
`nombre` VARCHAR(45) NOT NULL ,
`jugador` INT NULL ,
`categoria` INT NULL ,
PRIMARY KEY (`idEquipo`) ,
UNIQUE INDEX `idEquipos_UNIQUE` (`idEquipo` ASC) ,
INDEX `categoria` (`categoria` ASC) ,
INDEX `jugador` (`jugador` ASC) ,
CONSTRAINT `categoria`
FOREIGN KEY (`categoria` )
REFERENCES `futbol`.`Categoria` (`idCategoria` )
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT `jugador`
FOREIGN KEY (`jugador` )
REFERENCES `futbol`.`Equipo_Jugadores` (`jugador` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;


CREATE TABLE IF NOT EXISTS `futbol`.`Equipo_Jugadores` (
`idEquipo_Jugadores` INT NOT NULL AUTO_INCREMENT ,
`equipo` INT NULL ,
`jugador` INT NULL ,
PRIMARY KEY (`idEquipo_Jugadores`) ,
UNIQUE INDEX `idEquipo_Jugadores_UNIQUE` (`idEquipo_Jugadores` ASC) ,
INDEX `jugador` (`jugador` ASC) ,
INDEX `equipo` (`equipo` ASC) ,
CONSTRAINT `jugador`
FOREIGN KEY (`jugador` )
REFERENCES `futbol`.`Jugadores` (`idJugador` )
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `equipo`
FOREIGN KEY (`equipo` )
REFERENCES `futbol`.`Equipos` (`idEquipo` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
  #2 (permalink)  
Antiguo 26/07/2011, 16:10
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 5 meses
Puntos: 2658
Respuesta: Problemas creando relación M:N

Por lo pronto, has creado relaciones circulares, que son relaciones imposibles de administrar. Esto se da porque estás poniendo interdependencias que hace imposible crear las tablas tal y como lo planteas.
Además, ten en cuenta que la PK de una relación N:N está compuesta por las PK correspondientes a las tablas de origen, y sólo necesita un discriminante si puede darse que haya más de un par idéntico relacionado, que no es el caso.
Las FK no son transitivas, por lo que las tablas base no necesitan de la FK de laotra tabla, que ya está en el origen.
Otra cosa: Te olvidaste de una tabla (categorías), sin la cual el esquema no se puede crear.
El esquema sería mas o menos así:
Código MySQL:
Ver original
  1. DROP SCHEMA IF EXISTS `futbol` ;
  2. CREATE SCHEMA IF NOT EXISTS `futbol` DEFAULT CHARACTER SET latin1 ;
  3.  
  4. -- -----------------------------------------------------
  5. -- Table `futbol`.`equipos`
  6. -- -----------------------------------------------------
  7. DROP TABLE IF EXISTS `futbol`.`equipos` ;
  8.  
  9. CREATE  TABLE IF NOT EXISTS `futbol`.`equipos` (
  10.   `idEquipo` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT ,
  11.   `nombre` VARCHAR(45) NOT NULL ,
  12.   `categoria` INT(11) NULL DEFAULT NULL ,
  13.   PRIMARY KEY (`idEquipo`) ,
  14.   INDEX `categoria` (`categoria` ASC) )
  15. DEFAULT CHARACTER SET = latin1;
  16.  
  17.  
  18. -- -----------------------------------------------------
  19. -- Table `futbol`.`jugadores`
  20. -- -----------------------------------------------------
  21. DROP TABLE IF EXISTS `futbol`.`jugadores` ;
  22.  
  23. CREATE  TABLE IF NOT EXISTS `futbol`.`jugadores` (
  24.   `idJugador` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT ,
  25.   `nombre` VARCHAR(45) NULL DEFAULT NULL ,
  26.   `apellido` VARCHAR(45) NULL DEFAULT NULL ,
  27.   PRIMARY KEY (`idJugador`) )
  28. DEFAULT CHARACTER SET = latin1;
  29.  
  30.  
  31. -- -----------------------------------------------------
  32. -- Table `futbol`.`equipo_jugadores`
  33. -- -----------------------------------------------------
  34. DROP TABLE IF EXISTS `futbol`.`equipo_jugadores` ;
  35.  
  36. CREATE  TABLE IF NOT EXISTS `futbol`.`equipo_jugadores` (
  37.   `idEquipo` INT(11) NOT NULL ,
  38.   `idJugador` INT(11) NOT NULL ,
  39.   PRIMARY KEY (`idEquipo`, `idJugador`) ,
  40.   INDEX `fk_equipo_jugadores_equipos` (`idEquipo` ASC) ,
  41.   INDEX `fk_equipo_jugadores_jugadores1` (`idJugador` ASC) ,
  42.   CONSTRAINT `fk_equipo_jugadores_equipos`
  43.     FOREIGN KEY (`idEquipo` )
  44.     REFERENCES `futbol`.`equipos` (`idEquipo` )
  45.   CONSTRAINT `fk_equipo_jugadores_jugadores1`
  46.     FOREIGN KEY (`idJugador` )
  47.     REFERENCES `futbol`.`jugadores` (`idJugador` )
  48. DEFAULT CHARACTER SET = latin1;
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #3 (permalink)  
Antiguo 26/07/2011, 19:51
 
Fecha de Ingreso: febrero-2010
Mensajes: 52
Antigüedad: 14 años, 2 meses
Puntos: 3
De acuerdo Respuesta: Problemas creando relación M:N

Muchas gracias por aclararme mis errores de conceptos, me ha costado construirlo porque tenía marcado el unsigned data.
Voy a explicar lo que he entendido con mis propias palabras, menos técnicas que las tuyas, a ver si he entendido bien lo que he hecho.

Para crear una relación M:N entre dos relaciones, equipo-jugador en este caso, debo seguir los siguientes pasos:
1.- Creo una tabla Equipo_Jugadores en la que incluyo como claves primarias idjugador, idequipo.
2.- Defino dos claves foráneas, una para cada tabla y para cada id. idjugador con la tabla Jugadores y idequipo con la tabla Equipos.
3.- Ya está.

Muchas gracias de nuevo, ahora voy a ver si soy capaz de crear otra relación M:N que tengo en la misma bbdd.


Por cierto, la tabla Categoría no la he añadido pegándola aquí, porque no quería incluirla para dejarlo más claro, también tengo otras tablas con relación 1:N, pero esas tablas creo que las tengo bien puestas.
  #4 (permalink)  
Antiguo 27/07/2011, 05:24
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 5 meses
Puntos: 2658
Respuesta: Problemas creando relación M:N

Cita:
la tabla Categoría no la he añadido pegándola aquí, porque no quería incluirla para dejarlo más claro,

El problema es que el script que pusiste creaba una FK que apuntaba a la tabla CATEGORIAS, pero como no estaba, fallaba a la hora de crear la tabla.
Cuando posteas un script así te conviene poner todas las tablas que estén relacionadas, aunque no sean parte de la solución o del problema, o bien eliminar de lo que posteas todas las FK cuya tabla no estés posteando.

Cita:
Para crear una relación M:N entre dos relaciones, equipo-jugador en este caso, debo seguir los siguientes pasos:
1.- Creo una tabla Equipo_Jugadores en la que incluyo como claves primarias idjugador, idequipo.
2.- Defino dos claves foráneas, una para cada tabla y para cada id. idjugador con la tabla Jugadores y idequipo con la tabla Equipos.
3.- Ya está.
Te voy a dar un camino más fácil.
Como por definición del modelo, toda relación N:N genera una tabla relacional, todas las CASE tools del mercado te crean una tabla física cuando vinculas dos tablas a través de un conector N:N. Esto significa que, en el caso de MySQL Workbench, lo que debes hacer es:
1) Crea la tabla JUGADOR con su PK.
2) Crea la tabla EQUIPO con su PK.
3) Selecciona el conector de relación N:N y haz un click en cada tabla y verás que instantáneamente el Workbech crea una tabla nueva donde las dos PK aparecen componiendo la PK de la nueva tabla.
A partir de allí puedes agregar todos los atributos que se necesiten en esa relación.

Como podrás apreciar, las cosas ya están solucionadas... simplemente debes aprender a aprovecharlas.

Tips finales:

1) Cuando uses columnas de tipo TINYINT, SMALLINT, MEDIUMINT, INT o BIGINT, y no vayas a usar valores negativos decláralas UNSIGNED.
Al usarlas sin el UNSIGNED, la mitad del rango de representación queda perdido porque está reservado a los números negativos. Así, por ejemplo, un TINYINT va de -128 a +127, mientras que el UNSIGNED va de 0 a 255.
La idea es que aproveches el rango, y que recuerdes que no existen los ID negativos. De hecho, el auto_increment no genera valores negativos.
2) Trata de no usar "ID" como nombre de identificador de las PK de las tablas. A la larga genera confusiones en las consultas con JOIN.
Lo que es habitual es usar un prefijo con el nombre de la tabla, para poder recordarlo más fácilmente (tiene otras ventajas), tal como jugador_id, torneo_id, etc. Si te fijas, Workbench crea automáticamente la primera columna con el "id" como prefijo más el nombre de la tabla, cuando creas las tablas en el diagrama directamente.
Es una práctica general de los desarrolladores.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #5 (permalink)  
Antiguo 27/07/2011, 09:35
 
Fecha de Ingreso: febrero-2010
Mensajes: 52
Antigüedad: 14 años, 2 meses
Puntos: 3
De acuerdo Respuesta: Problemas creando relación M:N

Cita:
Iniciado por gnzsoloyo Ver Mensaje

El problema es que el script que pusiste creaba una FK que apuntaba a la tabla CATEGORIAS, pero como no estaba, fallaba a la hora de crear la tabla.
Cuando posteas un script así te conviene poner todas las tablas que estén relacionadas, aunque no sean parte de la solución o del problema, o bien eliminar de lo que posteas todas las FK cuya tabla no estés posteando.
Si, me olvidé de borrarlo correctamente, sorry.

Cita:
Iniciado por gnzsoloyo Ver Mensaje
Te voy a dar un camino más fácil.
Como por definición del modelo, toda relación N:N genera una tabla relacional, todas las CASE tools del mercado te crean una tabla física cuando vinculas dos tablas a través de un conector N:N. Esto significa que, en el caso de MySQL Workbench, lo que debes hacer es:
1) Crea la tabla JUGADOR con su PK.
2) Crea la tabla EQUIPO con su PK.
3) Selecciona el conector de relación N:N y haz un click en cada tabla y verás que instantáneamente el Workbech crea una tabla nueva donde las dos PK aparecen componiendo la PK de la nueva tabla.
A partir de allí puedes agregar todos los atributos que se necesiten en esa relación.

Como podrás apreciar, las cosas ya están solucionadas... simplemente debes aprender a aprovecharlas.
Lo acabo de hacer como indicas y realmente es más rápido, pero no me arrepiento de haberlo aprendido a hacer a lo pardillo, pero ahora usaré el método que me recomiendas.


Cita:
Iniciado por gnzsoloyo Ver Mensaje
Tips finales:

1) Cuando uses columnas de tipo TINYINT, SMALLINT, MEDIUMINT, INT o BIGINT, y no vayas a usar valores negativos decláralas UNSIGNED.
Al usarlas sin el UNSIGNED, la mitad del rango de representación queda perdido porque está reservado a los números negativos. Así, por ejemplo, un TINYINT va de -128 a +127, mientras que el UNSIGNED va de 0 a 255.
La idea es que aproveches el rango, y que recuerdes que no existen los ID negativos. De hecho, el auto_increment no genera valores negativos.
2) Trata de no usar "ID" como nombre de identificador de las PK de las tablas. A la larga genera confusiones en las consultas con JOIN.
Lo que es habitual es usar un prefijo con el nombre de la tabla, para poder recordarlo más fácilmente (tiene otras ventajas), tal como jugador_id, torneo_id, etc. Si te fijas, Workbench crea automáticamente la primera columna con el "id" como prefijo más el nombre de la tabla, cuando creas las tablas en el diagrama directamente.
Es una práctica general de los desarrolladores.
Aquí me quedo con la duda, porque según entiendo yo, creo que yo he usado prefijos cuando he declarado los PK, también porque Workbench los incluye.
Sobre los unsigned, lo usaré, pero me dió problemas pq a alguna PK la declaré como unsigned y entonces no me permitía crear la realción N:N, pero quizás haciéndolo con tu método pueda declararlo.
Muchas gracias de nuevo crack!!!!
  #6 (permalink)  
Antiguo 27/07/2011, 09:51
 
Fecha de Ingreso: febrero-2010
Mensajes: 52
Antigüedad: 14 años, 2 meses
Puntos: 3
Respuesta: Problemas creando relación M:N

Ya he entendido lo que me decías en el último punto, que no cree ID a secas y que le ponga siempre un prefijo o un sufijo xxxid o idxxx
  #7 (permalink)  
Antiguo 27/07/2011, 15:07
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 5 meses
Puntos: 2658
Respuesta: Problemas creando relación M:N

Exacto. La idea es precisamente esa, que no se llame sólo "ID".

En cuanto al problema para crear las relaciones de Fk con las columnas UNSIGNED, en el 99% de las ocasiones es porque una es UNSIGNED y la otra no. El 1% restante, es porque usas campos de diferente rango (INT contra BIGINT, por ejemplo, o SMALLINT contra INT).
Las FK deben ser del mismo tipo, rango y/o collation que la PK de origen. Siempre.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #8 (permalink)  
Antiguo 28/07/2011, 09:38
 
Fecha de Ingreso: febrero-2010
Mensajes: 52
Antigüedad: 14 años, 2 meses
Puntos: 3
Respuesta: Problemas creando relación M:N

Cita:
Iniciado por gnzsoloyo Ver Mensaje
En cuanto al problema para crear las relaciones de Fk con las columnas UNSIGNED, en el 99% de las ocasiones es porque una es UNSIGNED y la otra no. El 1% restante, es porque usas campos de diferente rango (INT contra BIGINT, por ejemplo, o SMALLINT contra INT).
Las FK deben ser del mismo tipo, rango y/o collation que la PK de origen. Siempre.
Ok, entonces el otro día cuando tuve que quitar los UNSIGNED, mi problema debía ser que eran tipos diferentes y en lugar de quitar las UNSIGNED que tenía, debería haber puesto todos los id a UNSIGNED?

Y tengo otra duda sobre prácticas buenas.
Cuando diseño una tabla, la PK la pongo idcategoria por ejemplo, al relacionar esta tabla con otra tabla, en la segunda tabla donde es foránea la llamo "categoría" sin el id, es recomendable esta práctica?
Lo digo porque al hacerlo así me creo que será más fácil para mi identificar donde es PK y donde no. Pero quizás esté pasando por alto algunas cosas que me llevarán a problemas que de momento no soy capaz de planear.
Gracias teacher.

Última edición por Bernardao; 28/07/2011 a las 12:25

Etiquetas: tabla
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 01:49.