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

¿Enlazar una tabla con si misma?

Estas en el tema de ¿Enlazar una tabla con si misma? en el foro de Mysql en Foros del Web. Hola, tengo un pequeño problema en el diseño de una base de datos y quiero saber que opinais los que tenéis más dominio del tema. ...
  #1 (permalink)  
Antiguo 15/07/2014, 13:02
 
Fecha de Ingreso: junio-2011
Ubicación: Asturias
Mensajes: 228
Antigüedad: 12 años, 11 meses
Puntos: 14
¿Enlazar una tabla con si misma?

Hola, tengo un pequeño problema en el diseño de una base de datos y quiero saber que opinais los que tenéis más dominio del tema.

Estoy creando una aplicación de gestión de perros y necesito almacenar en una base de datos información de cada perra (solo las hembras) con su madre y con su padre.

En principio tenía pensado hacer lo siguiente

Tabla perras
id
nombre
xxxx
xxxx
id_madre (enlazado a la misma tabla)
id_padre (enlazado a la tabla perros)


Tabla perros
id
nombre
xxxx
xxxx
xxxx

El problema es que me gustaría dejar el id de la madre como opcional (porque puede que no se conozca quien es la madre) y no se como hacer eso, porque a la hora de sacar los datos, no puedo hacer una consulta de manera correcta.

Mi pregunta es la siguiente
¿Está bien el diseño y se podría sacar los datos de una perra y los de su madre con una sola consulta?
¿Tendría que hacer una tabla intermedia para enlazar los datos?

Muchas gracias
  #2 (permalink)  
Antiguo 15/07/2014, 13:57
Colaborador
 
Fecha de Ingreso: enero-2007
Ubicación: México
Mensajes: 2.097
Antigüedad: 17 años, 4 meses
Puntos: 447
Respuesta: ¿Enlazar una tabla con si misma?

Hola javierflti:

Lo que tienes se llama es una referencia circular y si hay forma de obtener lo que quieres, sin embargo hay algunas consideraciones a tomar en cuenta.

En primer lugar, si hablas de atributos OPCIONALES, estos no deben formar parte de una tabla, sobre todo si deseas tener integridad referencial. Una llave (primaria o Foránea) NO PUEDE SER NULA, por lo tanto no podrías colocarla en una tabla...

Hay varias formas de modelar lo que quieres, sin embargo debes de considerar que es posible que en algunos casos no tengas información ni del padre ni de la madre... creo que el modelo que te pudiera funcionar sería un modelo de tres tabla: una donde almacenes el nombre de todos los perros, una donde relaciones aquellos perros de los que conoces el padre y otra aquellos de los que conoces la madre...

Sería más o menos así:

Código MySQL:
Ver original
  1. mysql> SELECT * FROM cat_perros;
  2. +----------+--------------+--------+
  3. | id_perro | nombre       | genero |
  4. +----------+--------------+--------+
  5. |        1 | perro uno    | M      |
  6. |        2 | perra dos    | H      |
  7. |        3 | perra tres   | H      |
  8. |        4 | perra cuatro | H      |
  9. |        5 | perro cinco  | M      |
  10. +----------+--------------+--------+
  11. 5 rows in set (0.00 sec)
  12.  
  13. mysql> SELECT * FROM padres;
  14. +----------+----------+
  15. | id_perro | id_padre |
  16. +----------+----------+
  17. |        1 |        1 |
  18. |        2 |        5 |
  19. |        5 |        5 |
  20. +----------+----------+
  21. 3 rows in set (0.00 sec)
  22.  
  23. mysql> SELECT * FROM madres;
  24. +----------+----------+
  25. | id_perro | id_madre |
  26. +----------+----------+
  27. |        2 |        4 |
  28. +----------+----------+
  29. 1 row in set (0.00 sec)

Observa que en la tabla PADRES y MADRES, ambos campos apuntan hacia la misma tabla (CAT_PERROS) por lo tanto, si quisieras obtener AMBOS NOMBRES, lo que tienes que hacer es poner dos veces la tabla pero con distintos ALIAS:

Código MySQL:
Ver original
  1. mysql> SELECT P.id_perro id_hijo, CP1.nombre nombre_hijo,
  2.     -> P.id_padre, CP2.nombre nombre_padre
  3.     -> FROM padres P
  4.     -> INNER JOIN cat_perros CP1 ON CP1.id_perro = P.id_perro
  5.     -> INNER JOIN cat_perros CP2 ON CP2.id_perro = P.id_padre;
  6. +---------+-------------+----------+--------------+
  7. | id_hijo | nombre_hijo | id_padre | nombre_padre |
  8. +---------+-------------+----------+--------------+
  9. |       1 | perro uno   |        1 | perro uno    |
  10. |       2 | perra dos   |        5 | perro cinco  |
  11. |       5 | perro cinco |        5 | perro cinco  |
  12. +---------+-------------+----------+--------------+
  13. 3 rows in set (0.00 sec)


Observa que utilizo dos veces la tabla cat_perros, pero con dos alias distintos (CP1, CP2), de tal manera que puedo relacionar de manera independiente cada tabla...

de esta manera, no importa si no tienes información de alguno de los padres, podrías obtener la información de cada perro más o menos así:

Código MySQL:
Ver original
  1. mysql> SELECT CP1.id_perro, CP1.nombre,
  2.     -> CP2.nombre padre,
  3.     -> CP3.nombre madre FROM cat_perros CP1
  4.     -> LEFT JOIN padres P ON CP1.id_perro = P.id_perro
  5.     -> LEFT JOIN cat_perros CP2 ON P.id_padre = CP2.id_perro
  6.     -> LEFT JOIN madres M ON CP1.id_perro = M.id_perro
  7.     -> LEFT JOIN cat_perros CP3 ON M.id_madre = CP3.id_perro
  8.     -> ORDER BY CP1.id_perro;
  9. +----------+--------------+-------------+--------------+
  10. | id_perro | nombre       | padre       | madre        |
  11. +----------+--------------+-------------+--------------+
  12. |        1 | perro uno    | perro uno   | NULL         |
  13. |        2 | perra dos    | perro cinco | perra cuatro |
  14. |        3 | perra tres   | NULL        | NULL         |
  15. |        4 | perra cuatro | NULL        | NULL         |
  16. |        5 | perro cinco  | perro cinco | NULL         |
  17. +----------+--------------+-------------+--------------+
  18. 5 rows in set (0.00 sec)

Se entiende el punto???

Saludos y espero que te sea de ayuda
Leo.
  #3 (permalink)  
Antiguo 16/07/2014, 12:33
 
Fecha de Ingreso: junio-2011
Ubicación: Asturias
Mensajes: 228
Antigüedad: 12 años, 11 meses
Puntos: 14
Respuesta: ¿Enlazar una tabla con si misma?

Gracias, a ver si lo puedo solucionar así
muchas gracias

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 20:55.